Make the user enter the credentials for specific pages - authentication

In my Grails 3.3.10 application I'm using Spring security plugin , for a specific pages that got critical information I need the user to enter the credentials again although this user logged in before while entering to the application, Any ideas to achieve this.

You can configure this in your application.groovy. For example
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/sensitivepage/**', access: ['ROLE_USER', 'isFullyAuthenticated()']]
]
Anything under /sensitivepage/ will require re-authentication.
It's explained in the Spring Security Documentation.

You can try to create a filter chain for endpoints that do need to log in again and register a custom filter. In that filter, you can revoke the existing token. Make these endpoints secure so that if a request comes without token then it would redirect the user to the login page.
Here is a sample code for your reference: (Please note that I haven't tried this scenario, it just a thought that I'm sharing here.)
<bean id="reauthenticateFilterChain" class="org.springframework.security.web.DefaultSecurityFilterChain">
<constructor-arg index="0" ref="reauthenticateResourceRequestMatcher"/>
<constructor-arg index="1">
<list>
<ref bean="reauthenticateFilter"/>
</list>
</constructor-arg>
</bean>
This is how you can register your custom filter chain.
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<ref bean="reauthenticateFilterChain"/>
</list>
</constructor-arg>
</bean>

Related

allow specific role in cas

I have a cas server that authenticate and send back some attributes corerectly. Now i want to add a service that check user roles in principal attributes and allow access to a service only if logged in user has the Specific role ( like admin role!).
I read about 'requiredHandlers' and thought it can help, but i can not make it work!
For service, i have something like this:
<bean class="org.jasig.cas.services.RegexRegisteredService">
<property name="id" value="1"/>
<property name="name" value="Admin panel service"/>
<property name="serviceId" value="http://localhost:8080/admin"/>
<property name="evaluationOrder" value="0"/>
<property name="ignoreAttributes" value="true"/>
<property name="requiredHandlers" value="supporterAuthenticationHandler"> <!-- this is what i found so far -->
</property>
</bean>
where supporterAuthenticationHandler is defined in authenticationManager
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
<constructor-arg>
<map>
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver"/>
<entry key-ref="primaryAuthenticationHandler"><null /></entry>
<entry key-ref="supporterAuthenticationHandler"><null /></entry>
</map>
</constructor-arg>
<property name="authenticationPolicy">
<bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy"/>
</property>
</bean>
And supporterAuthenticationHandler is a simple implemention of AuthenticationHandler (nothing implemented in it yet.
problem is i can not make cas to check supporterAuthenticationHandler so that i can go further (and probably fall into another hole where i need the new Principal with attributes).
Am i going completely the wrong way? Shall i check user role in my admin application? is it even possible to check roles with cas with different services?
This goes to the point that CAS is an authentication service not an authorization service. CAS only ensures that users are who they say they are not what they can do in an application (service).
please see this answer
https://security.stackexchange.com/questions/7623/can-central-authentication-service-cas-do-authorization

Jasig CAS LDAP - How to get roles

I have jasig 3.4.7 installed with OpenLDAP and ssl enabled. I can login through CAS to an account created in the LDAP : fine.
Now I need to declare services via the management interface : I realized I've no "admin" account. So I tried to add a group "ADMIN" to my user. My first question : is it the right way ?
I've contextSource declared this way :
<bean id="contextSource" class="org.jasig.cas.adaptors.ldap.util.AuthenticatedLdapContextSource">
What do I need in order CAS to retrieve my user admin group. I tried :
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=Groups"/>
<property name="groupRoleAttribute" value="cn"/>
<property name="groupSearchFilter" value="(uniqueMember={0})" />
</bean>
But DefaultLdapAuthoritiesPopulator is incompatible with jasig AuthenticatedLdapContextSource.
What bean should I use instead. I've seen some people dont use jasig context source but default spring org.springframework.ldap.core.support.LdapContextSource instead. Is it correct ? Would it help ?
Thanks,

spring-security : Using user's certificate to authenticate against LDAP

I managed to authentify the user against the Ldap using the username found in the certificate. What I would like to obtain is to authentify the user using directly the certificate on the Ldap.
I cannot found how to pass the certificate to the Ldap.
here is the current config (using the certificate's username) :
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
<bean name="userService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch"/>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
<bean name="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value=""/>
<constructor-arg value="sAMAccountName={0}"/>
<constructor-arg ref="contextSource" />
</bean>
<bean name="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="" />
<property name="groupSearchFilter" value="member={0}" />
<property name="searchSubtree" value="true" />
</bean>
I was looking in to this issue myself. I have yet to find an authentication stack that does X509->account resolution "right". I got hung up on the fact that Spring Security's UserDetailsService interface insists on a string uid for lookup, but in many cases it is impossible to derive such a UID from the information contained in an X509 certificate's subject (e.g. there are many cn=John Smith in the world, or even within a single organization, nor is email required in a certificate DN). The uniqueness of a certificate lies in the Issuer + Serial Number combination, not the Subject.
After looking through the API there are a couple ways to go about this. Either way probably precludes using the namespace and setting up the filter chain and beans yourself:
1) Implement your own AuthenticationUserDetailsService and bind this to the PreAuthenticatedAuthenticationProvider. By default, I believe, the namespace sets up a UserDetailsByNameServiceWrapper using the passed-in user-service-ref. Going this route means you have to do everything to set up the UserDetails, including granted authorities resolution. Of course you can delegate all this, but its more work.
2) If your LDAP store is keyed by some UID, and this is the route I am leaning towards, implement your own X509PrincipalExtractor and bind it to the X509AuthenticationFilter and return the string uid that your LDAPUserDetailsService is configured to expect. Within the extractor implement the logic to search your LDAP store for the stored certificate. I do not know of any strategies that will work across LDAP servers, the easiest way would be if your LDAP supports RFC4523 certificateMatch or certificateExactMatch and you can configure a search filter that will return you a unique account from which you can then return the attribute you need (e.g. sAMAccountName). If not, if your certificates contain a value that you can filter on (e.g. certificate cn = LDAP cn) that you can use to retrieve a candidate set of LDAP results for, extract their certificates to X509Certificate and do .equals() against the passed in certificate to find the account that matches and return its uid.
Set up the LDAP server to use SSL with client authentication.
Finally, I've implemented the following sollution in my NON-web application :
<bean id="x509ContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://hostname:389/DC=base,DC=com" />
<property name="authenticationStrategy">
<bean class="org.springframework.ldap.core.support.ExternalTlsDirContextAuthenticationStrategy">
<property name="sslSocketFactory">
<bean class="yourOwnSocketFactory"/>
</property>
<property name="shutdownTlsGracefully" value="true" />
</bean>
</property>
</bean>
where yourOwnSocketFactory takes the user's certificate to establish the TLS connection.
A successfull TLS connection means the user is authenticated. That's the case with a well configured LDAP, which should check the user including certificate revokation list.
Once the connection established, you have to recover the user's informations with a custom BindAuthenticator which could extract (X509PrincipalExtractor) Certificate DN (or other usefull info) to match the LDAP user.

Difference between Tomcat and JBoss in context of "Spring Security framework" deployment

I have an application that use Spring-Security framework with Jboss Server. Everything works fine. I can get account locked, bad credentials messages based on the authentication.
Now, I'm trying to move to configure the same thing with Tomcat. But, I don't get account locked, bad credentials messages. I just get "Unauthorized" for every wrong authentication. Can some body point me to What I am missing ? Here is the securitycontext.xml file content:
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="basicAuthenticationEntryPoint"/>
</bean>
<bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager">
</property>
</bean>
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<ref local="jaasAuthenticationProvider"/>
<ref local="casAuthenticationProvider"/>
</list>
</property>
</bean>

How do i exclude everything but text/html from a heritrix crawl?

On: Heritrix Usecases there is an Use Case for "Only Store Successful HTML Pages"
My Problem: i dont know how to implement it in my cxml File. Especially:
Adding the ContentTypeRegExpFilter to the ARCWriterProcessor => set its regexp setting to text/html.*. ...
There is no ContentTypeRegExpFilter in the sample cxml Files.
Kris's answer is only half the truth (at least with Heritrix 3.1.x that I'm using). A DecideRule return ACCEPT, REJECT or NONE. If a rule returns NONE, it means that this rule has "no opinion" about that (like ACCESS_ABSTAIN in Spring Security). Now ContentTypeMatchesRegexDecideRule (as all other MatchesRegexDecideRule) can be configured to return a decision if a regex matches (configured by the two properties "decision" and "regex"). The setting means that this rule returns an ACCEPT decision if the regex matches, but returns NONE if it does not match. And as we have seen - NONE is not an opinion so that shouldProcessRule will evaluate to ACCEPT because no decisions have been made.
So to only archive responses with text/html* Content-Type, configure a DecideRuleSequence where everything is REJECTed by default and only selected entries will be ACCEPTed.
This looks like this:
<bean id="warcWriter" class="org.archive.modules.writer.WARCWriterProcessor">
<property name="shouldProcessRule">
<bean class="org.archive.modules.deciderules.DecideRuleSequence">
<property name="rules">
<list>
<!-- Begin by REJECTing all... -->
<bean class="org.archive.modules.deciderules.RejectDecideRule" />
<bean class="org.archive.modules.deciderules.ContentTypeMatchesRegexDecideRule">
<property name="decision" value="ACCEPT" />
<property name="regex" value="^text/html.*" />
</bean>
</list>
</property>
</bean>
</property>
<!-- other properties... -->
</bean>
To avoid that images, movies etc. are downloaded at all, configure the "scope" bean with a MatchesListRegexDecideRule that REJECTs urls with well known file extensions like:
<!-- ...and REJECT those from a configurable (initially empty) set of URI regexes... -->
<bean class="org.archive.modules.deciderules.MatchesListRegexDecideRule">
<property name="decision" value="REJECT"/>
<property name="listLogicalOr" value="true" />
<property name="regexList">
<list>
<value>.*(?i)(\.(avi|wmv|mpe?g|mp3))$</value>
<value>.*(?i)(\.(rar|zip|tar|gz))$</value>
<value>.*(?i)(\.(pdf|doc|xls|odt))$</value>
<value>.*(?i)(\.(xml))$</value>
<value>.*(?i)(\.(txt|conf|pdf))$</value>
<value>.*(?i)(\.(swf))$</value>
<value>.*(?i)(\.(js|css))$</value>
<value>.*(?i)(\.(bmp|gif|jpe?g|png|svg|tiff?))$</value>
</list>
</property>
</bean>
The use cases you cite are somewhat out of date and refer to Heritrix 1.x (filters have been replaced with decide rules, very different configuration framework). Still the basic concept is the same.
The cxml file is basically a Spring configuration file. You need to configure the property shouldProcessRule on the ARCWriter bean to be the ContentTypeMatchesRegexDecideRule
A possible ARCWriter configuration:
<bean id="warcWriter" class="org.archive.modules.writer.ARCWriterProcessor">
<property name="shouldProcessRule">
<bean class="org.archive.modules.deciderules.ContentTypeMatchesRegexDecideRule">
<property name="decision" value="ACCEPT" />
<property name="regex" value="^text/html.*">
</bean>
</property>
<!-- Other properties that need to be set ... -->
</bean>
This will cause the Processor to only process those items that match the DecideRule, which in turn only passes those whose content type (mime type) matches the provided regular expression.
Be careful about the 'decision' setting. Are you ruling things in our out? (My example rules things in, anything not matching is ruled out).
As shouldProcessRule is inherited from Processor, this can be applied to any processor.
More information about configuring Heritrix 3 can be found on the Heritrix 3 Wiki (the user guide on crawler.archive.org is about Heritrix 1)