MVC应用5 - 实施OAuth授权code流 [英] MVC 5 application - implement OAuth Authorization code flow

查看:259
本文介绍了MVC应用5 - 实施OAuth授权code流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

href=\"http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server\">http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server,我已经创建了一个授权服务器,资源服务器和客户端的MVC。
MVC的客户端有一个控制器,它从资源服务器获取一些数据。资源服务器要求身份验证。 MVC的客户从授权服务器获得授权code和将用户重定向到授权服务器进行身份验证。最后,MVC客户交流授权code的访问令牌访问资源服务器。这是由2的OAuth协议中所述的授权code流动。这工作得很好。

Based on this tutorial http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server, I have created an Authorization Server, a Resource Server and a MVC Client. The MVC Client has a Controller which gets some data from the Resource Server. The Resource Server requires authentication. The MVC Clients gets an authorization code from the Authorization Server and Redirects the user to the Authorization Server for authentication. Finally the MVC Clients exchanges the authorization code for a Access token to Access the Resource Server. This is the Authorization code flow as described by the OAuth 2 protocol. This works fine.

现在,我必须使MVC客户端本身就需要身份验证的控制器的要求。我无法找到一个教程这一点。

Now, I have the requirement to make a Controller of the MVC Client itself require Authentication. I can not find a tutorial for this.

我添加

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

我Startup.Auth.cs。
我想,我需要设置选项重定向到授权服务器。我还可以设置提供的选项:

to my Startup.Auth.cs. I assume, I need to setup the Options to Redirect to the Authorization Server. I can also set the Provider on the Options:

app.UseOAuthBearerAuthentication(new Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationOptions()
{
    Provider = new OAuthBearerAuthenticationProvider()
});

但我还停留在落实提供商的事件。
任何人都可以指导我在正确的方向?还是有什么教程,这可能会帮助我吗?

But I am also stuck on implementing the events of the Provider. Can anybody guide me in the right direction? Or are there any tutorials which might help me?

推荐答案

我结束了基于从布洛克 - 阿伦这两篇文章的解决方案:

I ended up with a solution based on these two articles from Brock Allen:

该基波想法是注册两个认证的中间件。活跃​​的Cookie的身份验证和被动OAuthBearer的身份验证。在Startup.Auth.cs它们加入这样的:

The fundemental idea is to register two authentication Middlewares. An active Cookie-Authentication and a passive OAuthBearer-Authentication. In Startup.Auth.cs they are added like this:

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 - 控制器。其登录-方法将用户重定向到您的授权服务器的登录页面获取授权code。你必须提供一个回调函数,在那里你会处理授权code。

You also add an ExternalLogin-Controller. Its Login-method has to redirect the user to the Login-page of your Authorization Server to get the authorization code. You have to supply a callback function where you will process the authorization code.

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

在您的回调函数你交换授权code访问令牌(加刷新令牌),挑战你的被动OAuthBearer认证中间件和访问令牌作为Cookie登入。

In your callback-function you exchange the authorization code for an access token (plus refresh token) challenge your passive OAuthBearer-authentication Middleware and signin with the Access token as your 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, string>
    {
        {"client_id", "0123456789"}
        ,{"client_secret", "ClientSecret"}
        ,{"grant_type", "authorization_code"}
        ,{"code", authorizationCode}
        ,{"redirect_uri", _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授权code流动有用的人。

I hope this is useful for someone who is implementing the OAuth authorization code flow in his MVC 5 application.

这篇关于MVC应用5 - 实施OAuth授权code流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆