asg_backend/asg_form/Controllers/OAuthController.cs
2024-12-29 00:12:46 +08:00

140 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
[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}");
}
default:
throw new Exception($"没有实现【{type}】登录回调!");
}
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
}
}