// Generate an access token, given parameters in request that tell use what scopes to include, // and thus what resource's encryption key to use in addition to the authroization server key public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage) { var accessToken = new AuthorizationServerAccessToken { Lifetime = TimeSpan.FromMinutes(10) }; // could parameterize lifetime var targetResource = _resourceRepository.FindWithSupportedScopes(accessTokenRequestMessage.Scope); accessToken.ResourceServerEncryptionKey = targetResource.PublicTokenEncrypter; accessToken.AccessTokenSigningKey = _tokenSigner.GetSigner(); var result = new AccessTokenResult(accessToken); return(result); }
public ActionResult ProcessAuthorization(bool isApproved) { // Have DotNetOpenAuth read the info we need out of the request EndUserAuthorizationRequest pendingRequest = _authorizationServer.ReadAuthorizationRequest(); if (pendingRequest == null) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Missing authorization request."); } // Make sure the client is one we recognize Client requestingClient = _clientRepository.GetById(pendingRequest.ClientIdentifier); if (requestingClient == null) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Invalid request"); } // Make sure the resource is defined, it definitely should be due to the ResourceAuthenticated attribute Resource requestedResource = _resourceRepository.FindWithSupportedScopes(pendingRequest.Scope); if (requestedResource == null) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Invalid request"); } // See if authorization of this client was approved by the user // At this point, the user either agrees to the entire scope requested by the client or none of it. // If we gave capability for user to reduce scope to give client less access, some changes would be required here IDirectedProtocolMessage authRequest; if (isApproved) { // Add user to our repository if this is their first time var requestingUser = _userRepository.GetById(User.Identity.Name); if (requestingUser == null) { requestingUser = new User { Id = User.Identity.Name, CreateDateUtc = DateTime.UtcNow }; _userRepository.Insert(requestingUser); _userRepository.Save(); } // The authorization we file in our database lasts until the user explicitly revokes it. // You can cause the authorization to expire by setting the ExpirationDateUTC // property in the below created ClientAuthorization. _authorizationRepository.Insert(new Authorization { ClientId = requestingClient.Id, Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope), UserId = requestingUser.Id, ResourceId = requestedResource.Id, CreatedOnUtc = DateTime.UtcNow }); _authorizationRepository.Save(); // Have DotNetOpenAuth generate an approval to send back to the client authRequest = _authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name); } else { // Have DotNetOpenAuth generate a rejection to send back to the client authRequest = _authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest); // The PrepareResponse call below is giving an error of "The following required parameters were missing from the DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationFailedResponse message: error" // unless I do this..... var msg = (EndUserAuthorizationFailedResponse)authRequest; msg.Error = "User denied your request"; } // This will redirect to the client app using their defined callback, so they can handle // the approval or rejection as they see fit return(_authorizationServer.Channel.PrepareResponse(authRequest).AsActionResult()); }
protected override bool AuthorizeCore(HttpContextBase httpContext) { // Figure out what resource the request is intending to access to see if the // user has already authenticated to with it EndUserAuthorizationRequest pendingRequest = _authorizationServer.ReadAuthorizationRequest(); if (pendingRequest == null) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Missing authorization request."); } try { _targetResource = _resourceRepository.FindWithSupportedScopes(pendingRequest.Scope); // Above will return null if no resource supports all of the requested scopes if (_targetResource == null) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Bad authorization request."); } } catch (Exception) { throw new HttpException(Convert.ToInt32(HttpStatusCode.BadRequest), "Bad authorization request."); } // User is considered authorized if in possession of token that originated from the resource's login page, // Name of token is determined by the resource configuration string tokenName = _targetResource.AuthenticationTokenName; string encryptedToken = httpContext.Request[tokenName]; //could be in cookie if previously logged in, or querystring if just logged in if (string.IsNullOrWhiteSpace(encryptedToken)) { // No token, so unauthorized return(false); } // Validate this thing came from us via shared secret with the resource's login page // The implementation here ideally could be generalized a bit better or standardized string encryptionKey = _targetResource.AuthenticationKey; string decryptedToken = EncodingUtility.Decode(encryptedToken, encryptionKey); string[] tokenContentParts = decryptedToken.Split(';'); string name = tokenContentParts[0]; DateTime loginDate = DateTime.Parse(tokenContentParts[1]); bool storeCookie = bool.Parse(tokenContentParts[2]); if ((DateTime.Now.Subtract(loginDate) > TimeSpan.FromDays(7))) { // Expired, remove cookie if present and flag user as unauthorized httpContext.Response.Cookies.Remove(tokenName); return(false); } // Things look good. // Set principal for the authorization server IIdentity identity = new GenericIdentity(name); httpContext.User = new GenericPrincipal(identity, null); // If desired, persist cookie so user doesn't have to authenticate with the resource over and over var cookie = new HttpCookie(tokenName, encryptedToken); if (storeCookie) { cookie.Expires = DateTime.Now.AddDays(7); // could parameterize lifetime } httpContext.Response.AppendCookie(cookie); return(true); }