微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MVC 5应用程序 – 实现OAuth授权代码流程

基于本教程 http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server,我创建了一个授权服务器,一个资源服务器和一个MVC客户端.
MVC客户端具有从资源服务器获取一些数据的控制器.资源服务器需要身份验证. MVC客户端从授权服务器获取授权码,并将用户重定向到授权服务器进行身份验证.最后,MVC客户端交换访问令牌的授权码以访问资源服务器.这是OAuth 2协议所述的授权码流程.这工作正常

现在,我要求使MVC客户端的控制器本身需要验证.我找不到这个教程.

我补充说

app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationoptions());

到我的Startup.Auth.cs.
我假设,我需要设置重定向到授权服务器的选项.我也可以在选项上设置提供者:

app.USEOAuthBearerAuthentication(new Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationoptions()
{
    Provider = new OAuthBearerAuthenticationProvider()
});

但我也坚持执行提供商的事件.
任何人可以指导我正确的方向吗?还是有任何可能帮助我的教程?

解决方法

我结束了一个基于brock Allen这两篇文章解决方案:

> http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/
> http://brockallen.com/2014/01/09/a-primer-on-external-login-providers-social-logins-with-owinkatana-authentication-middleware/

基本思路是注册两个认证中间件.活动的Cookie验证和被动OAuthBearer-Authentication.在Startup.Auth.cs中,它们是这样添加的:

app.UseCookieAuthentication(new CookieAuthenticationoptions()
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,LoginPath = new PathString("/ExternalLogin/Login"),});
app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationoptions()
{
    AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,});

您还可以添加一个ExternalLogin-Controller.其登录方法必须将用户重定向到授权服务器的登录页面获取授权码.您必须提供一个回调函数,您将在其中处理授权码.

public async Task<ActionResult> Login(string returnUrl)
{
    if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null)
        returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery);

    if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl))
        _returnUrl = returnUrl;

    //callback function
    _redirectUrl = Url.Action("AuthorizationCodeCallback","ExternalLogin",null,Request.Url.Scheme);

    Dictionary<string,string> authorizeArgs = null;
    authorizeArgs = new Dictionary<string,string>
    {
        {"client_id","0123456789"},{"response_type","code"},{"scope","read"},{"redirect_uri",_redirectUrl}
        // optional: state
    };

    var content = new FormUrlEncodedContent(authorizeArgs);
    var contentAsstring = await content.ReadAsstringAsync();
    return Redirect("http://localhost:64426/oauth/authorize?" + contentAsstring);
}

在您的回调功能中,交换访问令牌(加刷新令牌)的授权代码会挑战您的被动OAuthBearer身份验证中间件,并使用Access令牌作为Cookie登录.

public async Task<ActionResult> AuthorizationCodeCallback()
{
    // received authorization code from authorization server
    string[] codes = Request.Params.GetValues("code");
    var authorizationCode = "";
    if (codes.Length > 0)
        authorizationCode = codes[0];

    // exchange authorization code at authorization server for an access and refresh token
    Dictionary<string,string> post = null;
    post = new Dictionary<string,{"client_secret","ClientSecret"},{"grant_type","authorization_code"},{"code",authorizationCode},_redirectUrl}
    };

    var client = new HttpClient();
    var postContent = new FormUrlEncodedContent(post);
    var response = await client.PostAsync("http://localhost:64426/token",postContent);
    var content = await response.Content.ReadAsstringAsync();

    // received tokens from authorization server
    var json = JObject.Parse(content);
    _accesstoken = json["access_token"].ToString();
    _authorizationScheme = json["token_type"].ToString();
    _expiresIn = json["expires_in"].ToString();
    if (json["refresh_token"] != null)
        _refreshToken = json["refresh_token"].ToString();

    //SignIn with Token,SignOut and create new identity for SignIn
    Request.Headers.Add("Authorization",_authorizationScheme + " " + _accesstoken);
    var ctx = Request.GetowinContext();
    var authenticateResult = await ctx.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);
    ctx.Authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
    var applicationCookieIdentity = new ClaimsIdentity(authenticateResult.Identity.Claims,DefaultAuthenticationTypes.ApplicationCookie);
    ctx.Authentication.SignIn(applicationCookieIdentity);

    var ctxUser = ctx.Authentication.User;
    var user = Request.RequestContext.HttpContext.User;

    //redirect back to the view which required authentication
    string decodedUrl = "";
    if (!string.IsNullOrEmpty(_returnUrl))
        decodedUrl = Server.UrlDecode(_returnUrl);

    if (Url.IsLocalUrl(decodedUrl))
        return Redirect(decodedUrl);
    else
        return RedirectToAction("Index","Home");
}

我希望这对于在他的MVC 5应用程序中实现OAuth授权代码流的人是有用的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐