asg_backend/asg_form/Controllers/OAuthController.cs

169 lines
7.2 KiB
C#
Raw Normal View History

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);
}
}
}
}