I have followed this tutorial Create a RESTful API with authentication using Web API and Jwt
I managed to get the authentication part working but the authorization part is not working(towards end of tutorial). If I add the jwt token with the word bearer in the authorization header it gives me 401 authorization denied.
I'm thinking maybe I need to create a custom authorization attribute.
- Is there any way to use the existing authorize attribute?
- What does the existing Authorize attribute look for in order to authorize a user(not including roles or users parameters in the authorize attribute) ?
Startup.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 https://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
var issuer = ConfigurationManager.AppSettings["Issuer"];
var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["Secret"]);
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { "Any" },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
}
});
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/Token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat(issuer)
});
}
}
CustomOAuthProvider
public class CustomOAuthProvider : OAuthAuthorizationServerProvider
{
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var blSecurity = new BLSecurity();
var user = blSecurity.LogonUser(context.UserName, context.Password);
if (!(user.ResponseType == Global.Response.ResponseTypes.Success))
{
context.SetError("Authentication Error", "The user name or password is incorrect");
return Task.FromResult<object>(null);
}
var ticket = new AuthenticationTicket(SetClaimsIdentity(context, user.LoggedOnUser), new AuthenticationProperties());
context.Validated(ticket);
return Task.FromResult<object>(null);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
private static ClaimsIdentity SetClaimsIdentity(OAuthGrantResourceOwnerCredentialsContext context, User user)
{
//Add User Claims
var identity = new ClaimsIdentity("JWT");
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("bn", user.BranchName));
identity.AddClaim(new Claim("fn", user.FirstName));
identity.AddClaim(new Claim("ln", user.LastName));
//Add User Role Claims
var blRole = new BLRole();
var roles = blRole.GetRolesByUserId(user.UserID);
if (roles != null && roles.Count > 0)
{
foreach (var role in roles)
{
identity.AddClaim(new Claim(ClaimTypes.Role, role.RoleName));
}
}
return identity;
}
}
CustomJwtFormat
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private static readonly byte[] _secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["secret"]);
private readonly string _issuer;
public CustomJwtFormat(string issuer)
{
_issuer = issuer;
}
public string Protect(AuthenticationTicket data)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
var signingKey = new HmacSigningCredentials(_secret);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(_issuer, null, data.Identity.Claims, issued.Value.UtcDateTime.ToLocalTime(), expires.Value.UtcDateTime.ToLocalTime(), signingKey));
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
if i add the jwt token with the word bearer
- dont forget about space between Bearer and token. LikeBearer mytokendata
. And did you checked your token here? - tym32167new JwtSecurityToken(_issuer, null, data.Identity.Claims,...
->new JwtSecurityToken(_issuer, “Any”, data.Identity.Claims,...
- tym32167