Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Nadia 30 posts 86 karma points
    Jan 24, 2017 @ 03:16
    Nadia
    0

    Creating a OAuth Authorization Server with Umbraco Member login

    Has anyone built a full OAuth Authorization Server?

    I am attempting to do so, but for some reason login doesn't redirect to the authorization after the OwinContext.Authentication.SignIn code, and I am at a dead end on where to proceed.

    I built a identity server based on this post and works well. https://our.umbraco.org/forum/developers/api-questions/74807-securing-a-custom-api-controller-with-oauth-plus-members

    And I am attempting to extend it to a full authorization server

    I added the following to my UmbracoAuthTokenServerExtensions

      var oAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                //generally you wouldn't allow this unless on SSL!
    
                AllowInsecureHttp = true,
                ApplicationCanDisplayErrors = true,
    
                TokenEndpointPath = new PathString("/oauth/token"), 
    
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                AuthorizeEndpointPath = new PathString("/oauth/authorize"),
                Provider = new MembersAuthServerProvider(membersAuthServerProviderOptions)
                {
                    OnValidateClientRedirectUri = ValidateClientRedirectUri,
                    OnValidateClientAuthentication = ValidateClientAuthentication,
    
    
                 },
                AuthorizationCodeProvider = new AuthenticationTokenProvider
                {
                    OnCreate = CreateAuthorisationCode,
                    OnReceive = ReceiveAuthorisationCode,
                },
                AccessTokenProvider = new AuthenticationTokenProvider
                {
                    OnCreate = CreateAccessToken,
                    OnReceive = ReceiveAccessToken,
                },
    
                // Refresh token provider which creates and receives referesh token
                RefreshTokenProvider = new AuthenticationTokenProvider
                {
                    OnCreate = CreateRefreshToken,
                    OnReceive = ReceiveRefreshToken,
                }
                //  AccessTokenFormat = new CustomJwtFormat(HttpContext.Current.Request.UserHostName)
            };
    
    
            // Token Generation
            app.UseOAuthAuthorizationServer(oAuthServerOptions);
            //app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
                LoginPath = new PathString(AuthPaths.LoginPath),
                LogoutPath = new PathString(AuthPaths.LogoutPath),
            });
    

    My Login controller

    [HttpPost]
            public async Task<ActionResult> LoginAuth(LoginViewModel model)
            {
                if (ModelState.IsValid)
                {
                    var user = await UserManager.FindAsync(model.Email, model.Password);
                    if (user != null)
                    {
                        await SignInAsync(user, true);
    
    
                        return RedirectToCurrentUmbracoPage();
                    }
                    ModelState.AddModelError("", "Invalid username/password");
                }
                return CurrentUmbracoPage();
            }
    
            private UmbracoMembersUserManager<UmbracoApplicationMember> _userManager;
            public UmbracoMembersUserManager<UmbracoApplicationMember> UserManager
            {
                get
                {
                    return _userManager ?? (_userManager = OwinContext
                        .GetUserManager<UmbracoMembersUserManager<UmbracoApplicationMember>>());
                }
            }
            protected IOwinContext OwinContext
            {
                get { return Request.GetOwinContext(); }
            }
            private async Task SignInAsync(UmbracoApplicationMember member, bool isPersistent)
            {
                OwinContext.Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    
                var userIdentity = await UserManager.CreateIdentityAsync(member, DefaultAuthenticationTypes.ApplicationCookie);
    
                OwinContext.Authentication.SignIn(
                            new AuthenticationProperties { IsPersistent = isPersistent },
                               userIdentity); 
            }
    

    And my Authorisation Controller

    public ActionResult Authorize()
        {
            if (Response.StatusCode != 200)
            {
                // TODO tidy this view and log.
                log.Warn(string.Concat("Authorize Error, Response Code:", Response.StatusCode ));
                return View("AuthorizeError");
            }
    
            // Get auth context and see if we have a ticket.
            var authentication = HttpContext.GetOwinContext().Authentication;
            var ticket = authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie).Result;
            var identity = ticket != null ? ticket.Identity : null;
            if (identity == null)
            {
                // No ticket - so challenge (results in redirect to /account/login)
                authentication.Challenge("Application");
                log.Info("Challenging Authorizaton");
                return new HttpUnauthorizedResult();
            }
    
            var scopes = (Request.QueryString.Get("scope") ?? "").Split(' ');
    
            var autoGrant = true;  // Not currently supporting the "grant" screen for any clients - implicit.
            var submitGrant = Request.HttpMethod == "POST" && (!string.IsNullOrEmpty(Request.Form.Get("submit.Grant")));
    
    
    
            if (submitGrant || autoGrant)
            {
                identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType);                
                foreach (var scope in scopes)
                {
                    identity.AddClaim(new Claim("urn:oauth:scope", scope));
                }
                authentication.SignIn(identity);
    
                log.Info("Grant Added");
            }
            else if (Request.HttpMethod == "POST" && (!string.IsNullOrEmpty(Request.Form.Get("submit.Login"))))
            {
                authentication.SignOut("Application");
                authentication.Challenge("Application");
                return new HttpUnauthorizedResult();
            }
    
            return View();
        }
    
  • Anton Korobkoff 3 posts 73 karma points
    1 week ago
    Anton Korobkoff
    0

    Hi, Nadia!

    I'm working on the same thing, completed all steps from the related topic, and now stuck. Did you solve it?

  • Nadia 30 posts 86 karma points
    1 week ago
    Nadia
    0

    hi, I never solved it. I ended up having to create a separate auth server, which called the umbraco authentication

  • Anton Korobkoff 3 posts 73 karma points
    1 week ago
    Anton Korobkoff
    0

    So I suppose you created OWIN OAuth Authorization Server, right? Could you share some tips for it, please?

  • Nadia 30 posts 86 karma points
    1 week ago
    Nadia
    1

    It was a while ago and I had to get something out quick, it was a bit of a hack.

    I created a standard out of the box .net oAuth Server.

    In the umbraco site I had the oAuth token system working,

    In the login controller on the Auth server I had this code

    WebClient client = new WebClient();
            string postData = string.Concat("grant_type=password&username=", model.Email,"&password=", model.Password);
            string igniteTokenPath = "https://umbracosite.com/oauth/token";
            try
            {
                string tokenInfo = client.UploadString(igniteTokenPath, postData);
                WebHeaderCollection headers = client.ResponseHeaders;
                Token token = JsonConvert.DeserializeObject<Token>(tokenInfo);
    
                authentication.SignIn(
                             new AuthenticationProperties { IsPersistent = model.RememberMe },
                                 new ClaimsIdentity(new[] { new Claim(ClaimsIdentity.DefaultNameClaimType, token.userName), new Claim("Id", token.Id) }, "Application"));
    
            }
    
  • John Bergman 370 posts 907 karma points
    1 week ago
    John Bergman
    0

    Are you wanting to have external things like mobile apps sign in, or do you want to replace the web site authentication?

  • Anton Korobkoff 3 posts 73 karma points
    1 week ago
    Anton Korobkoff
    0

    Hi John,

    I'm working on Oauth authorization for external clients like mobile apps and web apps with authcode and accesstoken, authorization code (with refresh token) grant flow. I want to make Umbraco receive redirect link, authorize user with login and password and then redirect to the link along with authcode. Using that code the client sends request for accesstoken and... that's it!

    I've tried really awesome add-on AuthU, but it works only with login/password.

    Have you seen any kind of solution for this?

Please Sign in or register to post replies

Write your reply to:

Draft