c# - User login not being authenticated using OWIN bearer tokens -
i'm working mvc app. login handle web api.
the issue i'm facing when click on login button in mvc app api generating token along user info. can't display user information in view.
the following code in accountcontroller
of mvc app
[httppost] [allowanonymous] [validateantiforgerytoken] public async task<actionresult> login(loginviewmodel model) { string token = token.gettoken(token.grant_type, model.email, model.password, token.client_id, token.client_secret); //token has appropriate data if debug if (!string.isnullorempty(token)) return redirecttoaction("index", "home"); return view(model); }
then in view have
@if (request.isauthenticated) { <p>@user.identity.getusername()</p> //this line blank }
the api looks this
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 }); using (authrepository _repo = new authrepository()) { applicationuser user = await _repo.finduser(context.username, context.password); if (user == null) { context.seterror("invalid_grant", "the user name or password incorrect."); return; } } var identity = new claimsidentity(context.options.authenticationtype); identity.addclaim(new claim(claimtypes.name, context.username)); identity.addclaim(new claim(claimtypes.role, "user")); 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 }, { "email", context.username }, }); var ticket = new authenticationticket(identity, props); context.validated(ticket); }
can tell me why request not being authenticated? missing
some things seem wrong me example
part i: login method
convention use grantresourceownercredentials
endpoint (/api/token
) receives credentials , returns access token.
by convention, endpoint replaces login(loginviewmodel)
method. should not using login()
method, suspect are.
- if using
login
method, returns original, unaltered view model credentials. loginviewmodel class may have token property in it, not populating it. so, login method authenticates user, doesn't authorize them because user never access token. - your
grantresourceownercredentials
method return token , populates claims. have client logic store access token , send in each request? - unless token in format jwt (json web tokens), suspect major challenge un-encrypt token access claims (e.g. username / email). meaning, wouldn't easy client extract claims access token unless jwt.
part ii: can tell me why request not being authenticated?
you are being authenticated. isn't forms authentication. there no cookie. razor calls identity not work when api returns access tokens.
in typical forms auth model:
credentials sent , validated (authenticated). if validation successful, user authorized (given access) client side cookie has encrypted access information , claims. owin middle-ware reads cookie on each request , populates httpcontext (identity
property on httpcontext
object.)
access token work flow:
is similar, except, since there no cookie, , no connection between api , client view other data returned in view models. httpcontext
not populated except on server side (web api), each time owin middle-ware reads access token.
so, razor call to
@user.identity.getusername()
will come empty.
solution: getting , storing user info on client
if want user information server, should cache username (and other info need) on client.
ways store user info on client browser:
- session storage
- local storage
- javascript singleton class (like angular service)
ways username
store username when user enters credentials (clear if authentication fails)
have dedicated end point (api method) return user info want
return claims in jwt's.
if change token type (in global.asax or startup.cs -- depending on how have configured) use jason web tokens, client able un-encode token , read claims json array.
a last option: can use both access tokens , cookies. can return access token , create cookie. suppress cookie auth web api ever configure web api.
a final thought: access tokens used level of security (cookies more vulnerable). purpose in using access tokens? such security more important if creating spa (single page app) angularjs. otherwise, cookie auth simpler work flow, and, unless feel need security, cookies preferable.
Comments
Post a Comment