I am working on an ASP.NET MVC client application. User is authenticated and authorized via another API application which returns token.
Currently, after client app recieves token from API, it saves token in session and sets form authentication cookie for app authorization.
FormsAuthentication.SetAuthCookie(TokenViewModel.Username, rememberMe);
HttpContext.Current.Session["AuthenticationToken"] = TokenViewModel;
Should i keep using form authentication, or just save token in session? or user OWIN here to authorize user.
Client app uses [Authorize] attribute.
If you are using [Authorize] attribute, by default the API will check for the access token in the Authorization header of the HTTP request, not in the cookie.
If you want to use the cookie, then go for forms authentication or customize the Authorize attribute to check for the token inside the cookie.
So, it's better to keep the token in session and at the same time manage it's lifetime(token expiry) explicitly. Apart from that, you can use refresh tokens to get new access token after or before the current one expires.
Related
I have an ASP.net MVC web application that uses Microsoft's Owin middleware (Microsoft.Owin.Security.OpenIdConnect) to configure OpenID Connect authentication. My identity provider (Okta) is configured to support refresh tokens and I have confirmed that it is working. When signing in, my application receives an Access, ID and Refresh Token as expected. These tokens are validated and returned to the client in a cookie called ".AspNet.Cookies" (the default). On each request, the cookie and these tokens are parsed into a set of claims. Great so far. 👍
The Owin (Katana) middleware does not appear to do anything further with the Refresh Token, so I have implemented a token client to request a new Access Token from my IdP using the Refresh Token. This is working as expected. 👍
Two questions:
When and where should the application check to see if the Access Token is expired and request a new one?
After receiving new a access, id, and refresh token, how and where should the application update the user identity, claims and cookie?
OWIN COOKIE UPDATES
I believe the comment at the end of this post has the type of code you can write - I remember using similar code a few years back.
With OWIN you are using a server side stack secured by cookies so I'm not sure where access tokens are actually used, but maybe one of these is true?
The C# back end uses tokens to call an API
The Web UI downloads tokens from the web back end and makes Ajax calls to an API
PATTERN FOR HANDLING EXPIRED TOKENS
The only reliable pattern to handle expiry is to do this in the API client code:
When you get a 401 response from the API
Try to refresh the token and retry the API call with a new access token
If you can't refresh the token, redirect the user to sign in again
I always implement this with 2 classes, as in this SPA code of mine:
ApiClient - handles API calls
Authenticator - handles OAuth calls
If the Web UI is getting tokens from the web back end and then calling an API, your web back end could provide MVC operations similar to those in my authenticator class:
getAccessToken - get the current access token, though it may fail with a 401
refreshAccessToken - use this if a 401 is received and you need a new token
TOKEN EXPIRY TIMES
It is also possible to check token expiry times in the background - to reduce the number of client 401s. This is not a full solution however, since 401s can occur for other reasons in addition to expiry.
Is the protocol for silently obtaining Access-Token in SPA while a user session in the Authorization Server (Auth0) is still active - Triggers a call to get updated user claims/roles from whichever social connection/database the user authenticated with?
If not, how should I update the silently re-obtained Access-Token from the Authorization Server with the accurate claims/roles?
One can supply prompt=none as a parameter in an authorization request sent a hidden iframe which will result in a new id_token sent back in the authorization response if the SSO session at the Provider is still valid.
Whats the best way to programmatically authenticate user using OAuth 2.0 Authentication Code Grant ?
Wondering if there is a way to combine step A and B as stated on the spec - https://www.rfc-editor.org/rfc/rfc6749#section-4.1, i.e pass user ID and password as part of authorize call ? Something like,
/authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&user_id=john.doe#mail&password=xxxx
I believe one way is to submit() the form returned by the Authorization server with user id and password. Taking this route would create a dependency on the form and any changes to it given it is not a public API.
The Authorization Code grant is designed to be used with a full browser i.e. should not be used to authenticate the user programmatically. In fact using it programmatically would defeat the purpose of OAuth 2.0 to not divulge the user's credentials to the Client.
Grants like Client Credentials and Resource Owner Password Credentials have been designed to be used with non-browser Clients.
Alternatively you could create an access_token and refresh_token for your Client in a browser using the Authorization Code grant, then pass the tokens to your non-browser Client so that it can use the refresh_token on its own to obtain a new access token when the old one expires.
I am developing an app for salesforce. For authentication I am using the web server flow.
In salesforce OAuth implementation the session id is the same as access token. When I get the new access token (through refresh token method), what's the proper method to pass it to the client. Should I explicitly set the session ID to the new access token?
Assuming you included the web or full scopes when requesting the OAuth 2.0 access token then it can be used interchangeably with a Session Id.
You put the access token into a sid cookie are redirect to the correct instance/pod.
Better yet, you can use the frontdoor.jsp to setup the required cookies. See Using frontdoor.jsp to login to Salesforce UI and Communities
The client can handle this by having some logic for handling a request to the Salesforce API which fails with an Unauthorized response. When an Unauthorized response is received the client can ask your web server for a new access token / session id.
Alternatively you'd have to use WebSockets or some push technology to push the new access token to the client when the web server refreshes the token.
Correct me if I'm not understanding something. I'm working with a fresh Web API application generated from a VS template.
The user does register right on the login page of the Web API app.
It appears that a user can register from outside the Web API app (from ANY device that knows the api/Accounts URL), but it requires passing sensitive information in plain text.
The sample ValuesController has the [Authorize].
Accessing /api/Values from the browser will throw a 401 if the user is not logged in.
Accessing /api/Values from Fiddler will also throw a 401 even if the user is logged in. This is because it requires an Authorize: Bearer header, which the access token isn't available from outside the web application.
There is a token endpoint that we can use to request a token from outside the app, but using the built-in token endpoint requires the user's username and password as plain text to be sent.
I guess all the work needs to be done from an external trusted client application (which must have access to the same database that stores user info). From the client application, how would I create an access token so that I can make a request that would have that access token in the header?
Suppose that I was able to achieve generating an acceptable access token from the client. Will the [Authorize] attribute still block access because the user would technically not be logged in? Or does [Authorize] actually log the user in if it doesn't result in a 401?
The AuthorizeAttribute will block access when the IsAuthenticated property of the current IIdentity is false. This is entirely separated from the access token.
Your steps are all right. But i think you are mixing you understanding of the last part with cookies authentication and token authentication.
Will the [Authorize] attribute still block access because the user
would technically not be logged in? Or does [Authorize] actually log
the user in if it doesn't result in a 401?
With cookie authentication this would be a problem that the user would technically need to be logged in and a valid session would need to exist on the server.
However this would not be the case on with token authentication. As long as you have a valid bearer token, you may access the api from any device.