Unable to use access="permitAll" - spring

I am using spring 4 and hibernate 5.
Below is the xml config for my spring security.
I have this line:
<intercept-url pattern="/android/download" access="permitAll" />
When i tried access from SOAPUI, all i get is
Authentication request failed: com.test.common.JwtTokenMissingException: No token found in request headers. Please login again!
com.test.common.JwtTokenMissingException: No token found in request headers. Please login again!
Is there something wrong with my config file? I do not wish to set to security="none" as i want it to go through spring security.
Could it be the order in which the authenication is done in my CustomAuthenticationFilter class?
XML file for spring security:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<sec:http auto-config="false" create-session="stateless" entry-point-ref="customEntryPoint" use-expressions="true">
<intercept-url pattern="/admin/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/agent/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/analysis/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC') or hasRole('OPS')" />
<intercept-url pattern="/android/download" access="permitAll" />
<intercept-url pattern="/android/**" access="hasRole('ADMIN') or hasRole('SNF_AGENT')" />
<intercept-url pattern="/audit/**" access="hasRole('ADMIN')" />
<intercept-url pattern="/auth/logout" access="isFullyAuthenticated()" />
<intercept-url pattern="/external/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('SV_IC') or hasRole('IC') " />
<intercept-url pattern="/index.xhtml" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/misc/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/mission/missions/search" access="isFullyAuthenticated()" />
<intercept-url pattern="/mission/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('SV_IC')" />
<intercept-url pattern="/report/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/request/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC') or hasRole('OPS')" />
<intercept-url pattern="/target/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC')" />
<intercept-url pattern="/trawling/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/**" access="denyAll" />
<sec:custom-filter ref="customAuthenticationFilter"
before="PRE_AUTH_FILTER" />
<sec:csrf disabled="true" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
<beans:bean id="customAuthenticationFilter"
class="com.test.common.CustomAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler"
ref="customSuccessHandler" />
</beans:bean>
<beans:bean id="customSuccessHandler" class="com.test.common.CustomSuccessHandler" />
</beans:beans>
/**EDITED **/
I missed out this portion of code for CustomAuthenticationFilter class:
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
{
String header = request.getHeader(this.tokenHeader);
if (request.getServletPath().contains(".xhtml"))
{
header = (String) request.getSession().getAttribute("token");
}
if (header == null || !header.startsWith(PropertiesUtil.TOKEN_HEADER))
{
throw new JwtTokenMissingException(msgProperty.getProperty(MessageUtil.ERR_AUTH_NO_TOKEN));
}
String authToken = header.substring(PropertiesUtil.TOKEN_HEADER.length());
JwtAuthenticationToken authRequest = new JwtAuthenticationToken(authToken);
return getAuthenticationManager().authenticate(authRequest);
}

permitAll means that any authentication, even AnonymousAuthenticationToken is allowed, however your request never makes it that far. You have a custom filter, I assume it is derived from AbstractAuthenticationProcessingFilter, and since the filter throws an exception when the header is missing, you request never makes it to the AuthenticationManager!
There are several ways to solve this, here are two.
Create another filterchain <sec:http...> for endpoints that do not require a token, and use AnonymousAuthenticationFilter for this filter chain.
Return AnonymousAuthenticationToken from your filter if the JWT header is missing.
Hope this helps.

Related

I am uploading a CSV file on JSP page with Spring security but on uploading it is showing "Unauthorised access page error 403 page"

My spring security configuration is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<debug/>
<http auto-config="true" use-expressions="true" disable-url-rewriting="true" >
<!-- RESOURCES -->
<intercept-url pattern="/pages/login/login.jsp" access="permitAll" />
<intercept-url pattern="/login*" access="isAuthenticated()" />
<intercept-url pattern="/pages/login*" access="permitAll" />
<intercept-url pattern="/pages/user*" access="hasAnyRole('ADMIN')" />
<intercept-url pattern="/user**" access="hasAnyRole('ADMIN')" />
<intercept-url pattern="/new.version**" access="hasAnyRole('ADMIN')" />
<intercept-url pattern="/pages/version**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/ver.htm?method=**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/rep.htm?method=**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/upload.htm?method=**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/pages/rep**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/pages/upload**" access="hasAnyRole('ADMIN','OPERATIONS')" />
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/image/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/include/**" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<!-- <intercept-url pattern="/images/**" access="permitAll" /> -->
<custom-filter ref="requestParamEncodingFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
<form-login
login-page="/pages/login/login.jsp"
default-target-url="/login.htm?method=login"
username-parameter="j_username"
password-parameter="j_password"
authentication-failure-url="/pages/login/login.jsp?login_error=1"
/>
<logout logout-success-url="/pages/login/login.jsp" invalidate-session="true" delete-cookies="JSESSIONID" />
<session-management session-fixation-protection="newSession" invalid-session-url="/pages/login/login.jsp" />
<csrf/> //csrf is enabled here
<headers>
<cache-control/>
<xss-protection/>
<frame-options policy="SAMEORIGIN"/>
</headers>
</http>
<authentication-manager>
<authentication-provider ref="customAuthProvider"/>
</authentication-manager>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<beans:bean class="com.test.component.security.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<beans:bean class="com.test.component.security.RequestParamEncodingFilter" id="requestParamEncodingFilter"/>
I am uploading a CSV file on JSP page and I have used Spring security but on uploading it is showing Unauthorised access page error 403 page when my csrf tag is enabled in spring security configuration. If I disable it my file is successfully uploaded.
No need to put csrf tag
Since it is enabled by default if you are using spring 4
As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration.
Check the link.
for spring 3 check link

Keycloak and Spring Security

Can anyone please show me how to migrate keycloak and spring security. I already follow step in http://keycloak.github.io/docs/userguide/keycloak-server/html/ch08.html#spring-security-adapter. but it dint work. Do i need to write my own provider?
my original spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd"
>
<http use-expressions="true">
<intercept-url pattern="/index" access="isAuthenticated()" />
<intercept-url pattern="/tasks" access="isAuthenticated()" />
<intercept-url pattern="/dashboard" access="isAuthenticated()" />
<intercept-url pattern="/resetPassword" access="isAuthenticated()" />
<intercept-url pattern="/settings/**" access="isAuthenticated()" />
<intercept-url pattern="/" access="isAuthenticated()" />
<intercept-url pattern="/sam/**" access="hasRole('mym_security_permission-002')" />
<intercept-url pattern="/admin/**" access="hasRole('mym_security_permission-005')" />
<intercept-url pattern="/committee/**" access="isAuthenticated()" />
<intercept-url pattern="/member/**" access="isAuthenticated()" />
<intercept-url pattern="/attachment/download/**" access="isAuthenticated()" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
login-processing-url="/perform_login"
authentication-failure-url="/login?error"
authentication-success-handler-ref="customAuthenticationSuccessHandler"
username-parameter="username"
password-parameter="password"
always-use-default-target="true"
/>
<!--success-handler-ref="customLogoutSuccessHandler" -->
<logout
logout-url="/perform_logout"
delete-cookies="true"
invalidate-session="true"
/>
<!-- enable csrf protection -->
<csrf/>
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
</http>
<authentication-manager alias="authenticationManager" erase-credentials="false">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
i change this xml to xml that provided by keycloak user guide. And i put keycloak.json in web-inf.
After i make the configuration on keycloak. i try to access my page then error page like below will appear:
We're sorry ...
Invalid parameter: redirect_uri
return url:http://localhost:8080/auth/realms/Meeting/protocol/openid-connect/auth?response_type=code&client_id=mym-apps&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2FApp%2Fsso%2Flogin&state=0%2Fd21c7ae9-b041-43e5-8135-8150e9895ee5&login=true
i already resolved this problem. I just fix my “valid redirect URIs” to http://localhost:8080/app/* and /app/*
please add web orgins in keycloak client

Spring XML using <bean>

This is a pretty simple question, I'm following a tutorial and I'm up to the point where I'm adding a passwordEncoder to my spring security, I have the following XML...
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/static/**" security="none" />
<http use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/*" access="isAuthenticated()" />
<!-- <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')"
/> -->
<!-- <intercept-url pattern="/listAccounts.html" access="isAuthenticated()"
/> -->
<!-- <intercept-url pattern="/post.html" access="hasAnyRole('supervisor','teller')"
/> -->
<!-- <intercept-url pattern="/*" access="denyAll" /> -->
<form-login />
<logout invalidate-session="true" logout-success-url="/"
logout-url="/logout" />
</http>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
</beans:beans>
The problem is the <bean class="org.spr.. line just at the bottom is erroring saying security namespace does not allow
I do understand this, but is there a way I can use the reference without having to add <security: to everything else?
In your XML declaration you are declaring that "security:" is the default namespace:
xmlns="http://www.springframework.org/schema/security"
you have to preface all the elements not found in the security namespace with their prefix... in this case bean is in beans namespace... so you would need to say, beans:bean
This declaration:
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
should be:
<beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>

Spring security switching to http after login. How can I keep it as https?

I am using Spring MVC and Spring Security. My redirects were switching https to http until I found this post. Spring MVC "redirect:" prefix always redirects to http -- how do I make it stay on https?. I also had to set the redirectHttp10Compatible property to false in my AjaxUrlBasedViewResolver.
The problem is that https still switches to http after login. Once I am logged in I can set my app back to https in the address bar and it will stick. Also, I am using IP authentication for most users in which case https stays thanks to the solution above.
I am trying to add redirectHtp10Compatible to login_security_check or something like that but am stuck. Here my security-config.xml.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<global-method-security pre-post-annotations="enabled" />
<http auto-config='true' access-denied-page="/login">
<intercept-url pattern="/static/styles/**" filters="none" />
<intercept-url pattern="/static/scripts/**" filters="none" />
<intercept-url pattern="/login/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/error/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/api/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/ajaxTimeOut" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/checkSystem" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/adminUser/**" access="ROLE_SSADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/ajaxTimeOut" login-processing-url="/login_security_check" authentication-failure-url="/login?login_error=t" default-target-url="/" always-use-default-target="true" />
<logout logout-url="/logout" logout-success-url="/"/>
<custom-filter position="PRE_AUTH_FILTER" ref="ipPreAuthFilter" />
</http>
<beans:bean id="ipAuthDetailsSource" class="com.mydomain.security.IPBasedPreAuthenticatedDetailsSource" />
<beans:bean id="ipPreAuthFilter" class="com.mydomain.security.IPPreAuthenticationFilter">
<beans:property name="authenticationManager" ref="preAuthManager" />
<beans:property name="authenticationDetailsSource" ref="ipAuthDetailsSource" />
</beans:bean>
<beans:bean id="preAuthManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="preAuthProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="preAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService" ref="preAuthUserService" />
</beans:bean>
<beans:bean id="preAuthUserService" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService" />
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder" >
<salt-source user-property="salt" />
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="userService" class="com.mydomain.security.UserServiceImpl" />
<beans:bean id="passwordEncoder" class="com.mydomain.security.PasswordEncoder">
<beans:constructor-arg value="256" />
</beans:bean>
Have you tried this:
<http>
<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
...
</http>
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-requires-channel
Got the solution.
<security:form-login login-page="/Login"
login-processing-url="/j_spring_security_check"
default-target-url="https://127.0.0.1/abcWeb/"
always-use-default-target="true"
authentication-failure-url="https://127.0.0.1/abcWeb/loginfailed"
/>
<security:logout logout-success-url="https://127.0.0.1/abcWeb/logout" />
I have added absolute path for login processing and for the rest I had added this p:redirectHttp10Compatible="false" to InternalViewResolver

Spring security switching to http after login. How can I keep https?

I am using Spring MVC and Spring Security. My redirects were switching https to http until I found this post. Spring MVC "redirect:" prefix always redirects to http -- how do I make it stay on https?. I also had to set the redirectHttp10Compatible property to false in my AjaxUrlBasedViewResolver.
The problem is that https still switches to http after login. Once I am logged in I can set my app back to https in the address bar and it will stick. Also, I am using IP authentication for most users in which case https stays thanks to the solution above.
I am trying to add redirectHtp10Compatible to login_security_check or something like that but am stuck. Here my security-config.xml.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<global-method-security pre-post-annotations="enabled" />
<http auto-config='true' access-denied-page="/login">
<intercept-url pattern="/static/styles/**" filters="none" />
<intercept-url pattern="/static/scripts/**" filters="none" />
<intercept-url pattern="/login/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/error/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/api/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/ajaxTimeOut" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/checkSystem" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/adminUser/**" access="ROLE_SSADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/ajaxTimeOut" login-processing-url="/login_security_check" authentication-failure-url="/login?login_error=t" default-target-url="/" always-use-default-target="true" />
<logout logout-url="/logout" logout-success-url="/"/>
<custom-filter position="PRE_AUTH_FILTER" ref="ipPreAuthFilter" />
</http>
<beans:bean id="ipAuthDetailsSource" class="com.mydomain.security.IPBasedPreAuthenticatedDetailsSource" />
<beans:bean id="ipPreAuthFilter" class="com.mydomain.security.IPPreAuthenticationFilter">
<beans:property name="authenticationManager" ref="preAuthManager" />
<beans:property name="authenticationDetailsSource" ref="ipAuthDetailsSource" />
</beans:bean>
<beans:bean id="preAuthManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="preAuthProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="preAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService" ref="preAuthUserService" />
</beans:bean>
<beans:bean id="preAuthUserService" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService" />
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder" >
<salt-source user-property="salt" />
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="userService" class="com.mydomain.security.UserServiceImpl" />
<beans:bean id="passwordEncoder" class="com.mydomain.security.PasswordEncoder">
<beans:constructor-arg value="256" />
</beans:bean>
Thanks.
Add the requires-channel attribute to your secure urls in the intercep-url nodes
just like this:
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="https" />

Resources