2024-12-29 00:12:46 +08:00
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using MrHuo.OAuth.Github;
|
|
|
|
|
using MrHuo.OAuth.Microsoft;
|
|
|
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
|
|
|
using System.Management;
|
|
|
|
|
using System.Security.Claims;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace asg_form.Controllers
|
|
|
|
|
{
|
|
|
|
|
public class OAuthController : Controller
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
private readonly RoleManager<Role> roleManager;
|
|
|
|
|
private readonly UserManager<User> userManager;
|
|
|
|
|
|
|
|
|
|
public OAuthController(
|
|
|
|
|
RoleManager<Role> roleManager, UserManager<User> userManager)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
this.roleManager = roleManager;
|
|
|
|
|
this.userManager = userManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[HttpGet("oauth/setpassword")]
|
|
|
|
|
public async Task<object> SetPasswordAsync(string username,string password, [FromServices] IOptions<JWTOptions> jwtOptions)
|
|
|
|
|
{
|
|
|
|
|
var user = await userManager.FindByNameAsync(username);
|
|
|
|
|
await userManager.AddPasswordAsync(user, password);
|
|
|
|
|
var claims = new List<Claim>();
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
|
|
|
|
|
var roles = await userManager.GetRolesAsync(user);
|
|
|
|
|
foreach (string role in roles)
|
|
|
|
|
{
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
|
|
|
|
}
|
|
|
|
|
string jwtToken = BuildToken(claims, jwtOptions.Value);
|
|
|
|
|
return jwtToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[HttpGet("oauth/{type}")]
|
|
|
|
|
public IActionResult Index(
|
|
|
|
|
string type,string recall,
|
|
|
|
|
[FromServices] GithubOAuth githubOAuth,
|
|
|
|
|
[FromServices] MicrosoftOAuth microsoftOAuth
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var redirectUrl = "";
|
|
|
|
|
switch (type.ToLower())
|
|
|
|
|
{
|
|
|
|
|
case "github":
|
|
|
|
|
{
|
|
|
|
|
redirectUrl = githubOAuth.GetAuthorizeUrl();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "microsoft":
|
|
|
|
|
{
|
|
|
|
|
redirectUrl = microsoftOAuth.GetAuthorizeUrl();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return NotFound($"没有实现【{type}】登录方式!");
|
|
|
|
|
}
|
|
|
|
|
return Redirect(redirectUrl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static string BuildToken(IEnumerable<Claim> claims, JWTOptions options)
|
|
|
|
|
{
|
|
|
|
|
DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds);
|
|
|
|
|
byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey);
|
|
|
|
|
var secKey = new SymmetricSecurityKey(keyBytes);
|
|
|
|
|
|
|
|
|
|
var credentials = new SigningCredentials(secKey,
|
|
|
|
|
SecurityAlgorithms.HmacSha256Signature);
|
|
|
|
|
var tokenDescriptor = new JwtSecurityToken(expires: expires,
|
|
|
|
|
signingCredentials: credentials, claims: claims);
|
|
|
|
|
return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet("oauth/{type}callback")]
|
|
|
|
|
public async Task<IActionResult> LoginCallback(
|
|
|
|
|
string type,
|
|
|
|
|
[FromServices] GithubOAuth githubOAuth,
|
2025-01-27 00:16:06 +08:00
|
|
|
|
[FromServices] MicrosoftOAuth microsoftOAuth,
|
2024-12-29 00:12:46 +08:00
|
|
|
|
[FromServices] IOptions<JWTOptions> jwtOptions,
|
|
|
|
|
[FromQuery] string code,
|
|
|
|
|
[FromQuery] string state)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
switch (type.ToLower())
|
|
|
|
|
{
|
|
|
|
|
case "github":
|
|
|
|
|
{
|
|
|
|
|
var authorizeResult = await githubOAuth.AuthorizeCallback(code, state);
|
|
|
|
|
if (!authorizeResult.IsSccess)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(authorizeResult.ErrorMessage);
|
|
|
|
|
}
|
|
|
|
|
var userinfo = await githubOAuth.GetUserInfoAsync(authorizeResult.AccessToken);
|
|
|
|
|
//如果该Gitgub用户不存在,则创建一个
|
|
|
|
|
var user = new User() { Id=20,UserName = $"gh{userinfo.Name}", Email = userinfo.Email };
|
|
|
|
|
if (user == null)
|
|
|
|
|
{
|
|
|
|
|
var user_new = await userManager.FindByNameAsync(userinfo.Name);
|
|
|
|
|
var r = await userManager.CreateAsync(user);
|
|
|
|
|
return Redirect($"https://commentary.idvasg.cn/oauth/next?username=gh{userinfo.Name}");
|
|
|
|
|
}
|
|
|
|
|
var claims = new List<Claim>();
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
|
|
|
|
|
var roles = await userManager.GetRolesAsync(user);
|
|
|
|
|
foreach (string role in roles)
|
|
|
|
|
{
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
|
|
|
|
}
|
|
|
|
|
string jwtToken = BuildToken(claims, jwtOptions.Value);
|
|
|
|
|
return Redirect($"https://commentary.idvasg.cn/oauth/loginok?token={jwtToken}");
|
2025-01-27 00:16:06 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "microsoft":
|
|
|
|
|
{
|
|
|
|
|
var authorizeResult = await microsoftOAuth.AuthorizeCallback(code, state);
|
|
|
|
|
if (!authorizeResult.IsSccess)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(authorizeResult.ErrorMessage);
|
|
|
|
|
}
|
|
|
|
|
var userinfo = await githubOAuth.GetUserInfoAsync(authorizeResult.AccessToken);
|
|
|
|
|
var user = new User() { Id = 20, UserName = $"ms{userinfo.Name}", Email = userinfo.Email };
|
|
|
|
|
if (user == null)
|
|
|
|
|
{
|
|
|
|
|
var user_new = await userManager.FindByNameAsync(userinfo.Name);
|
|
|
|
|
var r = await userManager.CreateAsync(user);
|
|
|
|
|
return Redirect($"https://commentary.idvasg.cn/oauth/next?username=gh{userinfo.Name}");
|
|
|
|
|
}
|
|
|
|
|
var claims = new List<Claim>();
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
|
|
|
|
|
var roles = await userManager.GetRolesAsync(user);
|
|
|
|
|
foreach (string role in roles)
|
|
|
|
|
{
|
|
|
|
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
|
|
|
|
}
|
|
|
|
|
string jwtToken = BuildToken(claims, jwtOptions.Value);
|
|
|
|
|
return Redirect($"https://commentary.idvasg.cn/oauth/loginok?token={jwtToken}");
|
|
|
|
|
|
|
|
|
|
break;
|
2024-12-29 00:12:46 +08:00
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
throw new Exception($"没有实现【{type}】登录回调!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return Content(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|