简体   繁体   English

如何设置 MVC 请求以使用 Oauth 2.0 访问令牌?

[英]How to setup MVC requests to use Oauth 2.0 access token?

I am working on an Asp.net Web API + MVC project.我正在开发一个 Asp.net Web API + MVC 项目。 While creating the project, I selected 'Individual User Accounts' option for authentication.在创建项目时,我选择了“个人用户帐户”选项进行身份验证。 After login, the provider issues access token and I use this token in HTTP header of ajax calls and it works fine with Ajax calls.登录后,提供者会发出访问令牌,我在 ajax 调用的 HTTP 标头中使用此令牌,它与 Ajax 调用一起工作正常。 I also have MVC actions which are used to navigate to different pages.我也有用于导航到不同页面的 MVC 操作。 These actions are protected using [Authorize] attribute of System.web.MVC.这些操作使用 System.web.MVC 的 [Authorize] 属性进行保护。 While navigating to these actions authorization fails and I am redirected to login page.虽然导航到这些操作授权失败,我被重定向到登录页面。 How do I configure Oauth 2.0 access token to be used in non ajax requests (MVC requests) also.如何配置 Oauth 2.0 访问令牌以用于非 ajax 请求(MVC 请求)。

Startup.Auth.cs:启动.Auth.cs:

public partial class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

        public static string PublicClientId { get; private set; }

        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseCookieAuthentication(new CookieAuthenticationOptions { 
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Home/Login"),
                LogoutPath = new PathString("/Account/LogOff"),
                ExpireTimeSpan = TimeSpan.FromHours(1.0),
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Configure the application for OAuth based flow
            PublicClientId = "self";
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true // dont use this for production,
            };

            // Enable the application to use bearer tokens to authenticate users
            app.UseOAuthBearerTokens(OAuthOptions);

        }

WebApiConfig.cs: WebApiConfig.cs:

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

ApplicationOAuthProvider.cs: ApplicationOAuthProvider.cs:

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
    {
        private readonly string _publicClientId;

        public ApplicationOAuthProvider(string publicClientId)
        {
            if (publicClientId == null)
            {
                throw new ArgumentNullException("publicClientId");
            }

            _publicClientId = publicClientId;
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
               OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = CreateProperties(user.UserName);
            AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }

        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }

            return Task.FromResult<object>(null);
        }

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            // Resource owner password credentials does not provide a client ID.
            if (context.ClientId == null)
            {
                context.Validated();
            }

            return Task.FromResult<object>(null);
        }

        public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
        {
            if (context.ClientId == _publicClientId)
            {
                Uri expectedRootUri = new Uri(context.Request.Uri, "/");

                if (expectedRootUri.AbsoluteUri == context.RedirectUri)
                {
                    context.Validated();
                }
            }

            return Task.FromResult<object>(null);
        }

        public static AuthenticationProperties CreateProperties(string userName)
        {
            IDictionary<string, string> data = new Dictionary<string, string>
            {
                { "userName", userName }
            };
            return new AuthenticationProperties(data);
        }
    }

ASP.Net MVC is a server side web app technology and [Authorize] actions expect to receive a cookie rather than checking for a token. ASP.Net MVC 是一种服务器端 Web 应用程序技术,[授权] 操作期望接收 cookie 而不是检查令牌。

Not sure if this is overridable and in this type of solution you often end up having to deal with an ugly mix of cookies / tokens / server side code / client side code.不确定这是否可以覆盖,在这种类型的解决方案中,您通常最终不得不处理 cookie / 令牌 / 服务器端代码 / 客户端代码的丑陋组合。

A more modern / cleaner separation is to develop a single page app + REST API instead.更现代/更清晰的分离是开发单页应用程序 + REST API。 Code tends to be simpler and it feels like a better fit for the requirements you mention.代码往往更简单,感觉更适合您提到的要求。

To see what I mean, maybe have a quick browse of the UI code in this sample: https://github.com/gary-archer/oauth.websample1要了解我的意思,请快速浏览此示例中的 UI 代码: https : //github.com/gary-archer/oauth.websample1

The repo links to some blog posts if it's an option you're interested in.如果您感兴趣,该存储库会链接到一些博客文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MVC应用中的Google OAuth访问令牌到期? - Google OAuth access token expiration in MVC app? OAuth 2.0如何验证令牌的到期日期 - OAuth 2.0 How to validate token expiration date OAuth 2.0如何验证令牌的到期日期 - OAuth 2.0 How to validate token expiration date 适用于MVC的OAuth 2.0-RequestToken如何工作? - OAuth 2.0 for MVC - How does the RequestToken work? MVC5使用哪个OAuth 2.0身份验证流程? - Which OAuth 2.0 Authentication Flow does the MVC5 use? 处理OAuth 2.0身份验证 - 在ASP.NET MVC应用程序中获取令牌重定向令牌响应 - Handle OAuth 2.0 Authentication - Get token redirect token response in ASP.NET MVC application OIDC、OAuth2.0 和 OAuth 客户端应用程序和资源服务器没有不同时访问令牌的作用 - OIDC, OAuth2.0 and role of access token when OAuth client application and resource server are not different ASP .NET MVC-如何在将来的REST调用中使用OAuth登录中的令牌 - ASP .NET MVC - How to use token from OAuth Sign In with future REST calls 如何在Web Api OAuth中获取访问令牌? - How to get access token in Web Api OAuth? 401在MVC API中使用Microsoft Azure Active Directory验证OAuth 2.0承载令牌时使用401 - 401 when authenticating an OAuth 2.0 bearer token with Microsoft Azure Active Directory in an MVC API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM