protected override void Seed(AuthenticationDb db) { // This method will be called after migrating to the latest version. Db.Operations repo = new Db.Operations(db); repo.InitializeClients(); repo.InitializeRoles(); }
public async Task <IHttpActionResult> ObtainLocalAccessToken(string provider, string externalAccessToken) { if (string.IsNullOrWhiteSpace(provider) || string.IsNullOrWhiteSpace(externalAccessToken)) { return(BadRequest("Provider or external access token is not sent")); } var verifiedAccessToken = await VerifyExternalAccessToken(provider, externalAccessToken); if (verifiedAccessToken == null) { return(BadRequest("Invalid Provider or External Access Token")); } IdentityUser user = null; using (Db.Operations ops = new Db.Operations()) { user = await ops.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id)); } bool hasRegistered = user != null; if (!hasRegistered) { return(BadRequest("External user is not registered")); } //generate access token response var accessTokenResponse = GenerateLocalAccessTokenResponse(user.UserName); return(Ok(accessTokenResponse)); }
public async Task <IHttpActionResult> PasswordReset(PasswordResetModel pwd) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } IdentityUser idUser = null; using (Db.Operations ops = new Db.Operations()) { idUser = await ops.FindUserByEmail(pwd.Email); if (idUser != null) { IdentityResult result = await ops.ResetPasswordAsync(idUser.Id, pwd.Token, pwd.Password); if (!result.Succeeded) { if (result.Errors != null && result.Errors.Count() > 0) { return(Redirect(pwd.FailUrl + "?error=" + GetErrorString(result))); } } else { return(Redirect(pwd.SuccessUrl)); } } } return(Ok()); }
public async Task <IHttpActionResult> Test() { using (Db.Operations db = new Db.Operations()) { Client client = db.FindClient("mainApp"); return(Ok("Client found. Allowed origin: " + client.AllowedOrigin)); } }
public async static void SetupClientsAndRoles() { using (Db.Operations repo = new Db.Operations()) { await repo.InitializeClients(); await repo.InitializeRoles(); } }
public async Task <IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } var verifiedAccessToken = await VerifyExternalAccessToken(model.Provider, model.ExternalAccessToken); if (verifiedAccessToken == null) { return(BadRequest("Invalid Provider or External Access Token")); } using (Db.Operations ops = new Db.Operations()) { IdentityUser user = await ops.FindAsync(new UserLoginInfo(model.Provider, verifiedAccessToken.user_id)); bool hasRegistered = user != null; if (hasRegistered) { return(BadRequest("External user is already registered")); } user = new IdentityUser() { UserName = model.UserName }; // TODO: We will need other fields in the User object IdentityResult result = await ops.CreateAsync(user); if (!result.Succeeded) { return(GetErrorResult(result)); } var info = new ExternalLoginInfo() { DefaultUserName = model.UserName, Login = new UserLoginInfo(model.Provider, verifiedAccessToken.user_id) }; result = await ops.AddLoginAsync(user.Id, info.Login); if (!result.Succeeded) { return(GetErrorResult(result)); } } //generate access token response var accessTokenResponse = GenerateLocalAccessTokenResponse(model.UserName); return(Ok(accessTokenResponse)); }
public async Task <IHttpActionResult> GetExternalLogin(string provider, string error = null) { string redirectUri = string.Empty; if (error != null) { return(BadRequest(Uri.EscapeDataString(error))); } if (!User.Identity.IsAuthenticated) { return(new ChallengeResult(provider, this)); } var redirectUriValidationResult = ValidateClientAndRedirectUri(this.Request, ref redirectUri); if (!string.IsNullOrWhiteSpace(redirectUriValidationResult)) { return(BadRequest(redirectUriValidationResult)); } ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); if (externalLogin == null) { return(InternalServerError()); } if (externalLogin.LoginProvider != provider) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); return(new ChallengeResult(provider, this)); } IdentityUser user = null; using (Db.Operations ops = new Db.Operations()) { user = await ops.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey)); } bool hasRegistered = user != null; redirectUri = string.Format("{0}#external_access_token={1}&provider={2}&haslocalaccount={3}&external_user_name={4}", redirectUri, externalLogin.ExternalAccessToken, externalLogin.LoginProvider, hasRegistered.ToString(), externalLogin.UserName); return(Redirect(redirectUri)); }
public async Task <IHttpActionResult> Register(AspNetUser userModel) { if (userModel == null) { return(BadRequest("User data is empty - cannot register user")); } if (!ModelState.IsValid) { return(BadRequest(ModelState)); } else if (Settings.UseEmailAsUsername && String.IsNullOrWhiteSpace(userModel.Email)) { return(BadRequest("Email must be provided")); } else if (!Settings.UseEmailAsUsername && String.IsNullOrWhiteSpace(userModel.UserName)) { return(BadRequest("Username must be provided")); } IHttpActionResult errorResult = null; using (Db.Operations ops = new Db.Operations()) { IdentityUser idUser = new IdentityUser() { UserName = Settings.UseEmailAsUsername ? userModel.Email : userModel.UserName, Email = userModel.Email, EmailConfirmed = false, PhoneNumber = userModel.PhoneNumber, PhoneNumberConfirmed = false, TwoFactorEnabled = false }; IdentityResult result = await ops.RegisterUser(idUser, userModel.Password); errorResult = GetErrorResult(result); if (errorResult != null) { return(errorResult); } else { userModel.IdentityUserId = idUser.Id; } } return(Ok()); }
/// <summary> /// GrantResourceOwnerCredentials is used to validate provided username and password when the grant_type is set to password /// </summary> /// <param name="context"></param> /// <returns></returns> public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var allowedOrigin = context.OwinContext.Get <string>("as:clientAllowedOrigin"); if (allowedOrigin == null) { allowedOrigin = "*"; } context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin }); ClaimsIdentity identity = null; using (Db.Operations _repo = new Db.Operations()) { IdentityUser user = await _repo.FindUser(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } IList <string> roles = await _repo.UserRoles(user.Id); identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); foreach (string role in roles) { identity.AddClaim(new Claim(ClaimTypes.Role, role)); } //identity.AddClaim(new Claim("sub", context.UserName)); } var props = new AuthenticationProperties(new Dictionary <string, string> { { "as:client_id", (context.ClientId == null) ? string.Empty : context.ClientId }, { "userName", context.UserName } }); var ticket = new AuthenticationTicket(identity, props); context.Validated(ticket); }
private string ValidateClientAndRedirectUri(HttpRequestMessage request, ref string redirectUriOutput) { Uri redirectUri; var redirectUriString = GetQueryString(Request, "redirect_uri"); if (string.IsNullOrWhiteSpace(redirectUriString)) { return("redirect_uri is required"); } bool validUri = Uri.TryCreate(redirectUriString, UriKind.Absolute, out redirectUri); if (!validUri) { return("redirect_uri is invalid"); } var clientId = GetQueryString(Request, "client_id"); if (string.IsNullOrWhiteSpace(clientId)) { return("client_Id is required"); } Client client = null; using (Db.Operations ops = new Db.Operations()) { client = ops.FindClient(clientId); } if (client == null) { return(string.Format("Client_id '{0}' is not registered in the system.", clientId)); } if (!string.Equals(client.AllowedOrigin, redirectUri.GetLeftPart(UriPartial.Authority), StringComparison.OrdinalIgnoreCase)) { return(string.Format("The given URL is not allowed by Client_id '{0}' configuration.", clientId)); } redirectUriOutput = redirectUri.AbsoluteUri; return(string.Empty); }
public static async Task <AspNetUser> GetCurrentUser() { AspNetUser user = new AspNetUser(); // Populate inherited AspNetUser fields IdentityUser idUser = null; using (Db.Operations _repo = new Db.Operations()) { idUser = await _repo.GetCurrentUser(); } if (idUser != null) { user.IdentityUser = idUser; } return(user); }
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context) { var allowedOrigin = context.OwinContext.Get <string>("as:clientAllowedOrigin"); context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin }); string hashedTokenId = Helper.GetHash(context.Token); using (Db.Operations _repo = new Db.Operations()) { var refreshToken = await _repo.FindRefreshToken(hashedTokenId); if (refreshToken != null) { //Get protectedTicket from refreshToken class context.DeserializeTicket(refreshToken.ProtectedTicket); var result = await _repo.RemoveRefreshToken(hashedTokenId); } } }
public async Task CreateAsync(AuthenticationTokenCreateContext context) { var clientid = context.Ticket.Properties.Dictionary["as:client_id"]; if (string.IsNullOrEmpty(clientid)) { return; } var refreshTokenId = Guid.NewGuid().ToString("n"); using (Db.Operations _repo = new Db.Operations()) { var refreshTokenLifeTime = context.OwinContext.Get <string>("as:clientRefreshTokenLifeTime"); var token = new RefreshToken() { Id = Helper.GetHash(refreshTokenId), ClientId = clientid, Subject = context.Ticket.Identity.Name, IssuedUtc = DateTime.UtcNow, ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime)) }; context.Ticket.Properties.IssuedUtc = token.IssuedUtc; context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc; token.ProtectedTicket = context.SerializeTicket(); var result = await _repo.AddRefreshToken(token); if (result) { context.SetToken(refreshTokenId); } } }
public async Task <IHttpActionResult> PasswordResetRequest(string email) { IdentityUser idUser = null; using (Db.Operations ops = new Db.Operations()) { idUser = await ops.FindUserByEmail(email); if (idUser != null) { try { // For the Password Reset Token to work: // Go to the Application Pool for the web site in IIS // Advanced Settings > Process Model > Load User Profile = True string resetToken = await ops.GetPasswordResetToken(idUser.Id); if (Settings.EmailClient != null && Settings.PasswordReset != null) { EmailMessage mailMessage = Settings.PasswordReset; mailMessage.To = new EmailAddress(email); mailMessage.PlainTextContent = mailMessage.PlainTextContent.Replace("{EmailAddress}", email).Replace("{Token}", HttpUtility.UrlEncode(resetToken)); mailMessage.HtmlContent = mailMessage.HtmlContent.Replace("{EmailAddress}", email).Replace("{Token}", HttpUtility.UrlEncode(resetToken)); await Settings.EmailClient.SendAsync(mailMessage); } return(Ok()); } catch (Exception ex) { return(BadRequest(string.Format("Password reset details could not be sent to {0}. Internal error: {1}", email, ex.Message))); } } } return(Ok()); }
public RefreshTokensController() { _repo = new Db.Operations(); }
/// <summary> /// The route of this method is defined by Settings.TokenEndpointPath endpoint, e.g. /token /// </summary> /// <param name="context"></param> /// <returns></returns> public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { // Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that // client are present on the request. If the web application accepts Basic authentication credentials, // context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. // If the web application accepts "client_id" and "client_secret" as form encoded POST parameters, // context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body. // If context.Validated is not called the request will not proceed further. string clientId = string.Empty; string clientSecret = string.Empty; #region Load ClientId and ClientSecret from the request bool BodyAuthentication = false; bool HeaderAuthentication = false; BodyAuthentication = context.TryGetFormCredentials(out clientId, out clientSecret); if (!BodyAuthentication) { HeaderAuthentication = context.TryGetBasicCredentials(out clientId, out clientSecret); if (!HeaderAuthentication) { AuthRequest authRequest = context.GetAuthRequest(); if (authRequest != null) { clientId = authRequest.client_id; clientSecret = authRequest.client_secret; } } } if (string.IsNullOrWhiteSpace(clientId)) { // Remove the comments from the below lines if you want to force sending clientId/secrects // once access token is obtained context.Rejected(); context.SetError("invalid_clientId", "ClientId should be sent."); return(Task.FromResult <object>(null)); } #endregion Client client = null; #region Validate Client from the database using (Db.Operations _repo = new Db.Operations()) { client = _repo.FindClient(clientId); } if (client == null) { context.SetError("invalid_clientId", string.Format("Client '{0}' is not registered in the system.", clientId)); return(Task.FromResult <object>(null)); } if (client.ApplicationType == Models.ApplicationTypes.NativeConfidential) { if (string.IsNullOrWhiteSpace(clientSecret)) { context.SetError("invalid_clientId", "Client secret should be sent."); return(Task.FromResult <object>(null)); } else { if (client.Secret != Helper.GetHash(clientSecret)) { context.SetError("invalid_clientId", "Client secret is invalid."); return(Task.FromResult <object>(null)); } } } if (!client.Active) { context.SetError("invalid_clientId", "Client is inactive."); return(Task.FromResult <object>(null)); } #endregion context.OwinContext.Set <string>("as:clientAllowedOrigin", client.AllowedOrigin); context.OwinContext.Set <string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString()); context.Validated(clientId); // This sets context.ClientId parameter return(Task.FromResult <object>(null)); }