问题
I have a web app MVC,using auth0 owin regular web app cookie based authentication.
This web app also has webapis which is used internally in the application. However i have a requirement to call this webapis from outside the application. So i created a restclient and tried to implement jwtbearerauthentication in application (but cookie based on authentication still in place).
Now when i call the webapi from other application it validates the bearer token gives no error however it redirects to login page due to cookie based authentication.
startup file:
public partial class Startup
{
private IPlatform platform;
public void ConfigureAuth(IAppBuilder app, IPlatform p, IContainer container)
{
platform = p;
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = System.TimeSpan.FromDays(2),
SlidingExpiration = true
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
var provider = new Auth0.Owin.Auth0AuthenticationProvider
{
OnReturnEndpoint = (context) =>
{
// xsrf validation
if (context.Request.Query["state"] != null && context.Request.Query["state"].Contains("xsrf="))
{
var state = HttpUtility.ParseQueryString(context.Request.Query["state"]);
AntiForgery.Validate(context.Request.Cookies["__RequestVerificationToken"], state["xsrf"]);
}
return System.Threading.Tasks.Task.FromResult(0);
},
OnAuthenticated = (context) =>
{
var identity = context.Identity;
//Add claims
var authenticationManager = container.Resolve<IAuthenticationManager>();
authenticationManager.AddClaims(identity);
if (context.Request.Query["state"] != null)
{
authenticationManager.AddReturnUrlInClaims(identity, context.Request.Query["state"]);
}
return System.Threading.Tasks.Task.FromResult(0);
}
};
var issuer = "https://" + ConfigurationManager.AppSettings["auth0:Domain"] + "/";
var audience = ConfigurationManager.AppSettings["auth0:ClientId"];
var secret = TextEncodings.Base64.Encode(TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["auth0:ClientSecret"]));
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
AllowedAudiences = new[] { audience },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
}
});
app.UseAuth0Authentication(
clientId: platform.ServerRole.GetConfigurationSettingValue("auth0:ClientId"),
clientSecret: platform.ServerRole.GetConfigurationSettingValue("auth0:ClientSecret"),
domain: platform.ServerRole.GetConfigurationSettingValue("auth0:Domain"),
provider: provider);
}
}
webapiconfig file:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new {id = RouteParameter.Optional});
config.Filters.Add(new AuthorizeAttribute());
ODataConfig.Setup(config);
var clientID = WebConfigurationManager.AppSettings["auth0:ClientId"];
var clientSecret = WebConfigurationManager.AppSettings["auth0:ClientSecret"];
config.MessageHandlers.Add(new JsonWebTokenValidationHandler()
{
Audience = clientID,
SymmetricKey = clientSecret
});
}
Currently creating the jwt token from below code and posting using postman in header just to check if it works.. but redirects to login page.
string token = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);
回答1:
I suspect what's happening is that your call to the API has a bearer token which fails validation (or there is no Authorize token at all), your API controller has an Authorize attribute, which, since there is no valid ClaimsPrincipal on the call throws 401. Auth0AuthenticationProvider picks that and assumes the call was to UI so redirects for user authentication. You may want to add an override in the Oauth0Provider to trap OnRedirectToIdP (or something like that), inspect the request and if it is to API, abot further handling and return Unauthorized. Remove any [Authorize] from your API and see whether it works then. Also make sure your startup does not require Authorize for all controllers. You may want to remove the authn part of your code (cookie and Oauth2Provider) and see whether you are getting to the API then.
来源:https://stackoverflow.com/questions/39739936/web-app-and-web-api-authentication-in-same-application