OKTA Session API - okta

Is there an API (we are using the OKTA Sign In Widget) to get the original res.idToken?
Reason I ask is that users might hit our site after logging in to a different site and we need the idToken. We can tell if the session exists of course..
oktaSignIn.session.exists((exists) => {
if (exists) { oktaSignIn.session.get((res) =>
But I don't see an idToken in there.
Thanks!

Can you use tokenManager to store the tokens?
After receiving the id token, you can add it a tokenManager. The token can later be retrieved from there.
Refer - https://github.com/okta/okta-signin-widget#oidc-tokenmanageraddkey-token

Well.. seems like I can get a new IDToken. The docs say this:
oktaSignIn.idToken.refresh(token, function (newToken) {
// New id_token with extended lifetime
});
My problem of course was that I did not have have a token to refresh. Turns out you can just do... (use null instead of a token)
oktaSignIn.idToken.refresh(null, function (newToken) {
// New id_token with extended lifetime
});
Hopefully this is not a bug but a feature :-)

Related

Should a Laravel SPA still use a CSRF token for security?

I ran into multiple difficulties with CSRF when building a small SPA with Laravel and Vue.js:
I use index.html as the only view, the rest is handled by vue-router using single file components (i.e. .vue files)
Because I'm not using PHP or Blade on the front, I can't inject csrf_token() into my view. Even if I did, the token would eventually expire, yet because the app has no (or very few) page refresh(es), it wouldn't know if the token changed, and it would eventually fail to make AJAX requests with the old token
Some answers suggest to pass the token in a cookie and then retrieve it with JS. This approach suffers from the same problem as above -- the SPA is never notified when the token changes
I could dig in the internal workings of Laravel and throw an event every time the token changes; the front-end could use Laravel Echo to listen to the changes, but then the question raises, is it even worth to bother?
Lastly, I was suggested to use JWT; however, as I understand, JWT is used for authentication purposes, while CSRF -- for every single request regardless of the HTTP verb or intent.
With the last two points in mind, do you think it is necessary/advisable to use a CSRF token in a Laravel SPA? And if so, what would be the best implementation (cookie with the token, dedicated route returning the token, or other)? If not, what are the alternatives?
Comments don't have enough space, so I'm adding this as an answer, but this is just a concept as I have extremely low experience with Vue.
From the docs
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
So the concept would be something like this:
Set a custom header from Laravel.
When building/starting up your Vue application, get the custom header and set it somewhere global.
When making a request, intercept it and add the CSRF token from the global storage
axios.interceptors.request.use(function (config) {
// Get your token from the place you stored it and add to the request
});
Intercept the response and store a new token
axios.interceptors.response.use(function (response) {
// Store the new CSRF token in the same place you stored the 1st one.
});
Loop forever

How are users authenticated and retrieved?

Having worked my way through this tutorial:
http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/
I now have the solution standing upright and I can issue JWT tokens (what I think of as 'login') and authenticate requests by passing in those tokens during subsequent calls.
What I'm not clear on is how the [Authorize] attribute is:
Recognising a user as authenticated
Retrieving a user from the database
Making that user available to my code
How I would add to the authentication process if I wanted to (perhaps including extra authentication logic after the exiting logic)
[EDIT] I understand that JWT tokens are being used to identify the user but I don't understand 'how' this is taking place. I also understand the middleware is doing it, but the workings of this are not clear.
with the [Authorize] attribute an AuthorizationFilter will added to the filter chain before the controller is called. This article illustrates that.
With the call to ConfigureOAuthTokenConsumption (Step 6 in the tutorial) you give the middleware the information it needs to validate and process tokens.
the authentication, i.e. check username and password, happens only before the token is issued in
public override async Task
GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) {
...
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
...
}
the AuthorizationFilter will only see the token and rely on the information in the token itself
this blog post gives you an example how you can access the username:
var currentPrincipal = ClaimsPrincipal.Current;
string userName = "Anonymous";
if (currentPrincipal.Identity.IsAuthenticated)
{
userName = currentPrincipal.Identity.Name;
}
the middleware gets the information from the token
you can add you own logic either before the token is issued in GrantResourceOwnerCredentials or add your own AuthorizationFilter if you need additonal logic when you receive the token. The blog post linked under 3. shows an example for that.

django rest framework - adding to views.obtain_auth_token

I have implemented Token Authentication with django rest framework and I can post username and password to /api-token-auth/ and get the token.
url(r'^api-token-auth/', token_views.obtain_auth_token)
In addition to the token, I want to get the User object related to the returned token.
How can I override/add to this view and also return the actual User object?
You can find the relevant view here:
https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/authtoken/views.py#L21
Assuming you've created some sort of User serializer already, you can basically take the user instance there and shove it into your UserSerializer. then add it to the response, something like the below.
...
user_serializer = UserSerializer(user)
return Response({'token': token.key, 'user': user_serializer.data})

Can CakePHP offer stricter user authentication (continuous throughout session)?

I am trying to create a suitable authentication check for a CakePHP service. Currently it appears that the user session is created initially during login, but never checked beyond this during a single session.
eg. Renamed the username, changing the password or ID in the user's database entry has no effect on the session.
Is there a preferred method for this type of, constantly checked, authentication? Essentially the user should be confirmed access at every request.
My current solution would involve extending the AuthComponent and storing a hash of the user data (including the encrypted password) and checking this at every request. I also considered storing the session ID in this same token, but noticed that CakePHP does not even use the session_start() function.
This functionality appears necessary for me, and I would have thought others would also require such a solution. I have yet to find Cake documentation or community solutions similar to what I need.
Well, you can use isAuthorized() function from AuthComponent. It's being called with every request.
public function isAuthorized($user){
return true; //allow the user to see the page
}
You can debug($user) to see the actual data and if you want "new" information from your database, you can always get them like this:
public function isAuthorized($user){
$current_user_from_database = $this->User->findById($user['id']);
if($current_user_from_database['User']['username'] != $user['username']){
$this->Session->setFlash('You\'ve changed the username. Please, login again.');
$this->redirect($this->Auth->logout);
return false;
}
return true;
}
Look at the API for more info and from the PDF book. You can look at this video about AuthComponent too. It's great.
If you need any more information or help, feel free to ask.
Btw. you have to configure AuthComponent in your Controller if you want isAuthorized() function to get called with every request.
If Session.timeout will work correctly with a setting of zero minutes, you're set. http://book.cakephp.org/2.0/en/development/sessions.html

Simple Authorization in MVC3 with Forms Authentication

I'm trying to do what should be a simple thing in MVC3.
I've got an application that uses forms authentication to authenticate users with a 3rd party SSO. The SSO, on successful login, posts back to a specific controller action on my application. I then call FormsAuthentication.SetAuthCookie(user,false);.
I'm trying to implement some level of authorization. Simply, a user can exist in a number of different roles, e.g. Admin and Developer. Some controller actions should only be available to certain roles. Details of which roles a user belongs to is obtained by making a call to another external API, which returns a simple JSON response indicating.
In theory, this should be as simple as doing something like this after I set the FormsAuthentication cookie:
string[] rolelist = GetRoleListForUserFromAPI(User.Identity.Name);
HttpContext.User = new GenericPrincipal(User.Identity, rolelist);
However, I can't call this directly after calling SetAuthCookie, because HttpContext.User isn't anything meaningful at this point.
I could try setting this on every request, but ever request to my app would mean a roundtrip API call.
The most promising approach I've seen so far is to create a custom Authorization attribute and override OnAuthorization to do something like this:
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (<some way of checking if roles have already been set for this user, or role cache has timed out>)
{
string[] rolelist = GetRoleListForUserFromAPI(filterContext.HttpContext.User.Identity.Name);
filterContext.HttpContext.User = new GenericPrincipal(filterContext.HttpContext.User.Identity,rolelist);
}
}
I could then use [MyCustomAuthorization(Roles="Admin")] in front of controller actions to make the magic happen.
However, I've no idea how to detect whether or not the current HttpContext.User object has had its roles set, or whether it was set over a certain time ago and another API trip is needed.
What's the best approach for this?
Another way would be to store the roles in the UserData property of the FormsAuthentcationTicket. This could be done with comma delimited string.
http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationticket.formsauthenticationticket
Then on AuthenticateRequest method, you could pull the ticket back, grab the roles data and assign it to the current user using a generic principal.
You should override PostAuthenticateRequest
protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
string[] rolelist = GetRoleListForUserFromAPI(User.Identity.Name);
HttpContext.User = new GenericPrincipal(User.Identity, rolelist);
}
}
It's invoked after forms authentication is finished with it's processing.
http://msdn.microsoft.com/en-us/library/ff647070.aspx
Update
I had the wrong method signature (just checked in one of my own applications).
My first thought is that you should investigate implementing a custom role provider. This might be overkill but seems to fit in with the role-based plumbing.
More info from MSDN here.
Much to the aghast of some, the session object ISNT a bad idea here.
If you use temp data, you already take a hit for the session.
Storing this data in the cookie, well - Forms auth tokens have already been exploited in the POET vulnerability from a year and a half ago, so in that case someone could've simply formed their own cookie with the "admin" string in it using that vulnerability.
You can do this in post authenticate as #jgauffin mentioned.
If the session state isn't available there you can use it then in Application_PreRequestHandlerExecute and check it there.
If you want to check if session state is available in either see my code at:
How can I handle forms authentication timeout exceptions in ASP.NET?
Also whenever using forms auth and sessions, you always want to make sure the timeouts are in sync with each other (again the above code)

Resources