身份验证问题-使用API​​身份验证服务器的安全Web应用程序

时间:2019-09-20 07:02:16

标签: security model-view-controller asp.net-identity owin bearer-token

我已经开始创建自己拥有的软件体系结构:

  • Auth_API-作为身份验证服务器
  • Resource_API-作为资源API(受Auth_API保护)
  • WebApplication(mvc)-前端应用程序(受Auth_API保护)。

根据https://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/的文章,我已经成功进行了Google身份验证。

WebApp ==重定向到==> Auth_API ==挑战==> Google ==> API接收externalAccessToken,在本地注册用户并返回 localAccessToken

现在,当我想使用承载授权(使用本地访问令牌)时,一切正常。 但是我也想使用(cookie?)ClaimsIdentity登录到ASP MVC应用程序。

我当时正在考虑改用JWT,但是我不确定应该走哪条路...

代码位:

  1. Auth_API-获取本地访问令牌

    /// <summary>
    /// Returns local access token for already registered users
    /// </summary>
    /// <param name="provider"></param>
    /// <param name="externalAccessToken"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    [Route("ObtainLocalAccessToken")]
    public async Task<IHttpActionResult> ObtainLocalAccessToken(string provider, string externalAccessToken)
    {
        if (string.IsNullOrWhiteSpace(provider) || string.IsNullOrWhiteSpace(externalAccessToken))
        {
            return BadRequest("Provider or external access token is not sent");
        }
    
        var verifiedAccessToken = await VerifyExternalAccessToken(provider, externalAccessToken);
        if (verifiedAccessToken == null)
        {
            return BadRequest("Invalid Provider or External Access Token");
        }
    
        IdentityUser user = await _repo.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id));
    
        bool hasRegistered = user != null;
    
        if (!hasRegistered)
        {
            return BadRequest("External user is not registered");
        }
    
        //generate access token response
        var accessTokenResponse = GenerateLocalAccessTokenResponse(user.UserName);
    
        return Ok(accessTokenResponse);
    }
    
  2. 生成本地访问令牌算法

        private JObject GenerateLocalAccessTokenResponse(string userName)
    {
        var tokenExpiration = TimeSpan.FromDays(1);
    
        ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
    
        identity.AddClaim(new Claim(ClaimTypes.Name, userName));
        identity.AddClaim(new Claim("role", "user"));
    
        var props = new AuthenticationProperties()
        {
            IssuedUtc = DateTime.UtcNow,
            ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
        };
    
        var ticket = new AuthenticationTicket(identity, props);
    
        var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
    
        JObject tokenResponse = new JObject(
                                    new JProperty("userName", userName),
                                    new JProperty("access_token", accessToken),
                                    new JProperty("token_type", "bearer"),
                                    new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString()),
                                    new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()),
                                    new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString())
        );
    
        return tokenResponse;
    }
    
  3. Web应用程序-登录操作的一部分:

        if (hasLocalAccount)
        {
            var client = new RestClient(baseApiUrl);
            var externalLoginUrl = "Account/ObtainLocalAccessToken";
            var externalLoginRequest = new RestRequest(externalLoginUrl, Method.GET);
            externalLoginRequest.AddQueryParameter("provider", provider);
            externalLoginRequest.AddQueryParameter("externalAccessToken", externalAccessToken);
    
            var externalLoginResponse = client.Execute(externalLoginRequest);
    
            if (externalLoginResponse.IsSuccessful)
            {
                JObject response = JObject.Parse(externalLoginResponse.Content);
                string localAccessToken = response["access_token"].Value<string>();
                string localTokenExpiresIn = response["expires_in"].Value<string>();
    
                // WHAT TO DO WHERE TO SIGN IN A USER ??? 
                //AuthenticationTicket ticket = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(localAccessToken);   <== this returns NULL
    
                return RedirectToAction("Index", "Home");
            }
        }
    

0 个答案:

没有答案