spring security logout trigger - spring-mvc

I want to remove logged out user from a Hashmap I have for logged in users but I don't find the way to do this as when I press the logout link. It just redirected to login page.
In spring security I have
<logout invalidate-session="true"
logout-success-url="/"
logout-url="/logout.htm"/>
logout link is like
Logout
When I press this link it just go to my login mapping
#RequestMapping("login")
public ModelAndView login(){}
and when I try to get user detail using
SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
it returns me anonymous user. So how can I get the logged out user detail.
Please let me know if you need more details.

Add an implementation of org.springframework.security.web.authentication.logout.LogoutSuccessHandler interface as a bean to your security context.
Then you can use it:
<logout success-handler-ref="yourLogoutSuccessHandler" />
EDIT.
As mentioned by Marcel this solution will not work out of the box because you can't mix success-handler-ref and logout-success-url attributes (reference). I prefer slightly different solution : instead of inheritance, you can use composition:
Prepare configuratio for SimpleUrlLogoutSuccessHandler bean.
Set up logout-success-url via corresponding defaultTargetUrl property.
Inject SimpleUrlLogoutSuccessHandler bean into your CustomUrlLogoutSuccessHandler using LogoutSuccessHandler interface and call it after doing your stuff.
Advantage is that you will be less coupled with a framework code. So you will have less problems in a case of migration from Spring Security 3.1 to Spring Security Y.Y

The hint about the LogoutSuccessHandler is correct. However, you have to consider that configuring success-handler-ref and logout-success-url are mutually exclusive if I'm not mistaken. Hence, you need to implement the forwarding to URL manually in your success handler. Pointer: https://stackoverflow.com/a/6770785/131929

Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
authentication.getName()

In your applicationContext-security.xml file add the success-handler like below
< logout logout-url="/resources/j_spring_security_logout" success-handler-ref="com.mycompany.security.SpringSecurityLogoutHandler" />
Create the Class which will be implemneting org.springframework.security.web.authentication.logout.LogoutHandler interface and in it's logout method do all the stuff you want at the time of logout.

Related

Authorizing <app-route> paths using <firebase-auth> in Polymer 1.0

Just getting started with Polymer 1.0. My Single Page Polymer 1.0 application has multiple routes.
<paper-drawer-panel id="mainPanel" class="flex" >
<app-router id="router" class="flex" mode="pushstate">
<app-route path="/" element="page-landing"></app-route>
<app-route path="/user" element="page-user"></app-route>
<app-route path="/admin" element="page-admin"></app-route>
....// more <app-routes>
</app-router>
</paper-drawer-panel>
I would like to use <firebase-auth> with google as provider on landing page <page-landing>;
On Successful Authentication, I would like to navigate to <app-route> paths based on authorization
<page-admin> only ADMIN can see
<page-user> any logged in user can see
Say <page-landing> provides option to login as Admin or User.
How do I implement Authorization based routes? And in all <app-routes> I need to check the user isAuthorized or not. Could any one please point to an example of implementing this?
Have a look at iron-meta to store pagewide states like isAuthorized.
For distinguishing between secured pages and public once, you have to take care yourself. Use a change observer for the page path or selecteditem or similar.
Regarding authentication and authorization you are in bad luck, because all subpages are imported via the html link tag and you cannot attach any header.
But actually it is not really a problem. Because in general you like to secure the data of each page and not the whole itself. And html import only loads the view/page-template and you still have to populate it with the client data. This you usually request with an ajax call, which you can give an auth-header as normal.
Hope these descriptions help you find your way...

Response from Jasig CAS

I'm working with a servlet in which I want to add filters to log in with cas, and after successful login, i need to get some information from authentication (I need username and usergroup). So, in order to understand how to do that, can someone tell me, or refer me to a documentation, what's the response from CAS and what's in it? Thank you in advance.
If you are using CAS with Spring Security you can use AuthenticationSuccessHandler for this. You can get all the information from "authentication" parameter.
If you are not, you can override some methods of the filter you are using for ticket validation. There are onSuccessfulValidation and onFailedValidation methods in AbstractTicketValidationFilter which are empty by default. You can extend the filter you are using and override these methods. The information will be available under "assertion" parameter.
Last of all i think you can create your own filter and in that filter check if the user is logged in and retrieve the desired inforation. But since i haven't used CAS without Spring Security i am not sure the desired information will be available to you there.

where sfGuard checks out perms and credentials in order to implement Google's Oauth 2

I want to integrate Google's Oauth2 in my symfony-1.4 CRM. I have successfully implemented this, I have extended sfGuardAuth in my own module, and now mysfGuardAuth is being used for siging and signout. Is there where I handle Google's Oauth2 with 2 extra actions:
executeCkeckGoogleAccess();
executeOauth();
The problem is to checkout if Google's token is still a valid one, I have to redirect in each action of everymodule to the action checkGoogleAccess in mysfGuardAuth module.
What I want is to check this in an implicit way in the same place where symfony, or sfGuard or whatever checks for the right perms or credentials before executing or not executing the requested action.
I only want to write the code once.
Thank you.
After some research this is how sfGuard checks everything.
When you make a request to a module action, before the action is executed, a new sfContext is dispached.
The sfContext gets the user that extends sfGuardUser and has some methods that are executed. There is where perms, session status and everithing else is checked
The user must be configured in apps/yourApp/lib
By default is apps/yourApp/lib/myUser which extends sfGuardUser. The most apropiate way to achieve this is to create a new user class like: apps/yourApp/lib/yourAppUser which extends aswell sfGuardUser, and there extend the methods initialize and/or shutdown with the functionality you want.
By this way I have achieved to get Google's Oauth2 working in my app.
I hope this is usefull for more people.
UPDATE
All described above is true, but if you want to check something always before an action execution you must use filters instead of whats described before.
Filters are executed before each action, so there you can checkout whatever you need having access to the current context, and set up new attributes for the user. In my case I wanna check if the requested action needs a google token, if true, then Another filter will check if the user has alraedy a valid token, in that case, nothing happens, otherwise, the user is redirected to the module/action which handles google token requests.
Comunication between diferent filters, actions and requests are handled via user attributes.
the user is an object of the clas myOwnUser which extends sfGuardSecurityUser, there the function signOut is extended in order to delete all attributes saved in "myOwnNamespace"

Call a piece fo CAS login webflow

I have a CAS 3.4.9 using the login webflow.
I need to call directly the login webflow at a particular action/view.
How can it be done?
If it is not possible (I believe a security reason), How can have on CAS another "service" using another webflow?
And in this manner, what is the link I must use to call it?
Thank you.
You have two options. Extending the class in which you want to make the call, for instance at generateServiceTicket, or create a new class and inject your class into the CAS login webflow.
I have injected a trap in my CAS login webflow to check to see if a user has accepted a policy in the last 365 days.
Normally in the warn decision state, it will return the redirect action state, but instead I am trapping the user so the policy will be checked.
<decision-state id="warn">
<if test="flowScope.warnCookieValue" then="showWarningView" else="checkPolicy" />
</decision-state>
It then transitions into my checkPolicy state
<action-state id="checkPolicy">
<evaluate expression="checkPolicyAction"/>
<transition on="success" to="redirect"/>
<transition on="error" to="viewLoginForm"/>
<transition on="redirectPolicy" to="redirectPolicy"/>
<transition on="gateway" to="redirectPolicy"/>
</action-state>
The expression checkPolicyAction is defined in the cas-servlet.xml to the java class which executes the doExecute method and returns back to the webflow various states as you see in the previous xml. Just to top it off, redirectPolicy redirects the user to a new service that will then have them accept the policy and they can then continue on to what they intended to do.
Take a look at https://github.com/Unicon/cas-password-manager - This is where a company has extended the login-webflow of CAS to trap for password updates. This is where I got most of my ideas on how to trap the user. Also the CAS User Manual https://wiki.jasig.org/display/CASUM/ is a great resource.

Does Role Provider cache per request?

My MVC application makes use of a User's Role in multiple places during individual page requests. My question is whether the default SqlRoleProvider caches the current User's Roles for the lifetime of a page-request?
For example, I make use of Roles in attributes on Controller methods:
[Authorize(Roles = "Admin")]
and custom code
if (user.IsInRole(MembershipRole.Admin))
{
// Do something
}
else if (user.IsInRole(MembershipRole.Printer))
{
// Do something else
}
If the Role Provider does not cache roles, is the best solution to write a custom Role Provider that inherits from the default one, and override the methods to get the Roles once and cache them for the Request duration? Can this be done in a way that both the Authorize attribute and my own code will make use of the cached roles?
(In case you were wondering, I don't want to use the cacheRolesInCookie web.config option to cache the roles in cookies).
Thanks in advance for any suggestions.
[Edit to include details triggered from Joe's answer]
I decompiled System.Web.Mvc.AuthorizeAttribute and the AuthorizeCore method calls the following method for each role to be checked:
httpContext.User.IsInRole
Then peering into System.Web.Security.RolePrincipal (which is what "User" is above) both the methods below do indeed use a cached copy of the User's roles (or populates the cache if empty):
public string[] GetRoles()
public bool IsInRole(string role)
The cache is stored as a field on User, so its lifetime is for the duration of the request.
The methods find the roles using:
Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)
so will use whatever role provider you have chosen for the application (default or custom).
If you use a RoleProvider in an ASP.NET or ASP.NET MVC application, then HttpContext.User will reference a RolePrincipal which does cache roles for the lifetime of the request.
However, in a WCF service that uses ASP.NET roles:
<behavior ...>
<serviceAuthorization principalPermissionMode ="UseAspNetRoles"
roleProviderName ="MyRoleProvider" />
</behavior>
this is not true: instead HttpContext.User will reference the internal class System.ServiceModel.Security.RoleProviderPrincipal, which does not cache roles: instead it always calls RoleProvider.IsUserInRole.
The out-of-the-box RoleProviders don't do any caching, so this can result in repeated connections to the underlying data store. It seems like a deficiency to me: it would have been easy to cache the roles on first access.
is the best solution to write a custom Role Provider that inherits from the default one, and override the methods to get the Roles once and cache them for the Request duration?
Not necessary for ASP.NET or ASP.NET MVC, but could be envisaged for WCF. Caching for the Request duration will presumably use HttpContext.Items, so will introduce a dependency on the existence of HttpContext, but that's not necessarily a problem except for making unit testing harder.
Can this be done in a way that both the Authorize attribute and my own code will make use of the cached roles?
If you configure your custom RoleProvider in web.config there's nothing more you need to do so that the Authorize attribute will use it.

Resources