Spring Security sec:authorize throw exception - spring

I want to add a field to my jsp which will be shown only to admin. For this purpose I use tag sec:authorize access="hasRole('Admin')". But when I add it, application throws exception: http://pastebin.com/TcN0k0K0
I use spring 4.1.7.RELEASE, spring-security version 4.0.3.RELEASE. In pom.xml I've added spring-security-taglibs v.4.0.3
here is my jsp code:
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<html>
<body>
<sec:authorize access="hasRole('Admin')">
<p>Must have ROLE_Admin to see this</p>
</sec:authorize>
<form name='registerForm' method='POST' action="/admin/createuser">
...
in database role stored as ROLE_Admin, ROLE_User
spring-security.xml
<?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:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<http use-expressions="true" >
<csrf disabled="true"/>
<intercept-url pattern="/admin" access="hasAnyRole('Admin', 'User')" />
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<access-denied-handler error-page="/403" />
<form-login login-page='/login' login-processing-url="/login" authentication-failure-url="/403"
default-target-url="/admin"
username-parameter="login" password-parameter="password" />
<logout logout-url="/logout" logout-success-url="/logoutSuccessful" delete-cookies="JSESSIONID" invalidate-session="true" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="myDataSource"
users-by-username-query= "select login, password, 'true' from employee where login=?"
authorities-by-username-query= "select login, role from employee where login =? " />
</authentication-provider>
</authentication-manager>
<beans:import resource="data-source-cfg.xml"/>
</beans:beans>
How to fix this problem?

take a look at this post, the problem you are getting is about the spring version. You have two options:
1 - To keep using spring security 4.0.3 you must upgrade Spring version for 4.2.x.
2 - To keep using your current spring version you must downgrade to the Spring security 4.0.2
Best Regards

Related

Multiple spring security configuration not working

In my application i want to have separate spring security implementation based on url patterns.
Eg. /rest/ ** will have its own authentication provider(basic auth) and
/web/ ** will have its own authentication provider(form login).
please find below configuration i have done
<?xml version="1.0"?>
<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.xsd">
<!-- config for rest services using basic auth-->
<http pattern="/rest/**">
<intercept-url pattern="/MyAppRestServices" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<http-basic />
</http>
<!-- AUTHENTICATION MANAGER FOR CUSTOM AUTHENTICATION PROVIDER -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
<!-- config for web using form login-->
<http pattern="/web/**">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<form-login/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="nimda" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
In above config first config is working fine ie restservice with basic auth but web with form login config is not working. its not even intercepting the url ?
Please let me know whats wrong with above config ?
Kindly refer below working configuration for web authentication::
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/css/**" security="none" />
<http pattern="/images/**" security="none" />
<http pattern="/js/**" security="none" />
<http auto-config="false" authentication-manager-ref="dev" use-expressions="true" disable-url-rewriting="true">
<intercept-url pattern="/admin/login" access="permitAll" />
<intercept-url pattern="/admin/*" access="isAuthenticated()" />
<form-login
login-page="/admin/login"
default-target-url="/admin/workbench"
username-parameter="username"
password-parameter="password"
authentication-failure-url="/admin/login"
/>
<logout logout-success-url="/admin/login" logout-url="/j_spring_security_logout" invalidate-session="true" delete-cookies="JSESSIONID" />
</http>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- STATIC USER -->
<authentication-manager id="dev" alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="abc" password="pwd" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>

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

<beans> to <beans:beans> - element beans must be declared

In the code below, why do I get "element must be declared" (From IntelliJ) if I change the start / end tags from "beans" to "beans:beans"?
What's the significance of the ":beans"?
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- HTTP security configurations -->
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
<logout logout-url="/j_spring_security_logout" />
<intercept-url pattern="/login" requires-channel="https"/>
<intercept-url pattern="/backend/**" access="isAuthenticated()" />
<intercept-url pattern="/todoes/**" access="isAuthenticated()" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
<remember-me key="mySecondSecretWordThatShouldBeHidden" user-service-ref="userAccountDetailsService" />
</http>
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />
<!-- Configure Authentication mechanism -->
<beans:bean name="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
<beans:constructor-arg name="secret" value="myVerySecretWordThatShouldBeSomewhereHidden"/>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userAccountDetailsService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
You have bound the security schema to the default namespace using xmlns=.... This means you can use the elements in that namespace directly without qualification, e.g. <authentication-manager>.
To use an element defined in another schema you need to bind that schema to another namespace and use that as a prefix. Declaring xmlns:beans="http://www.springframework.org/schema/beans" binds the schema identified by the URL to the namespace beans. The location of the schema is in the xsi:schemaLocation. Example usage <beans:bean>. Had you declared the namespace as xmlns:wibble="http://www.springframework.org/schema/beans", then this would change to <wibble:bean>.
You could have used any of them as your default namespace, which one makes sense depends on your config file and the types of bean it will have.

spring security redirects to last requested page after login session timeout

I have implemented spring security for login to my web portal. It works fine except for one issue. I have set session timeout to 5 min. Once timeout happpens and then user click any URL, it gets redirected to logout page.
But when user re autheticates, user directly lands on the last access page instead of home page which is default target URL.
Spring security file is as below:
<?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"
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.0.xsd">
<http auto-config="true">
<intercept-url pattern="/index.jsp" access="ROLE_ADMIN,ROLE_USER" />
<intercept-url pattern="/home.html" access="ROLE_ADMIN,ROLE_USER" />
<intercept-url pattern="/mdm/accessToken.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/enroll.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/installApp.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/checkStatus.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/searchDevice.html" access="ROLE_USER" />
<intercept-url pattern="/admin/*" access="ROLE_ADMIN" />
<intercept-url pattern="/account/*" access="ROLE_ADMIN" />
<intercept-url pattern="/user/*" access="ROLE_USER" />
<form-login login-page="/login.html" default-target-url="/home.html"
authentication-failure-url="/loginfailed.html" />
<logout logout-url="/logout.html" logout-success-url="/logoutSuccess.html" invalidate-session="true" />
<anonymous username="guest" granted-authority="ROLE_GUEST" />
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
<session-management invalid-session-url="/logout.html" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select USER as username, password, 'true' as enabled from TBL_USER_MASTER where user=?"
authorities-by-username-query="select um.USER as username , rm.ROLE_NAME as authorities from TBL_USER_MASTER um,TBL_ROLE_MASTER rm
where um.USER=? and um.role_id=rm.role_id" />
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
Add the always-use-default-target attribute to your form-login tag.
<form-login always-use-default-target="true" />
If set to true, the user will always start at the value given by default-target-url, regardless of how they arrived at the login page. Maps to the alwaysUseDefaultTargetUrl property of UsernamePasswordAuthenticationFilter. Default value is false.
In Grails, this setting solves the problem in Config.groovy
grails.plugin.springsecurity.successHandler.alwaysUseDefault = true

Spring security concurrent session is not working as desired

Instead of restricting one session per user,it is restricting one session for
whole application.
So if one user is logged in noone can login .
Here is my configuration
<session-management invalid-session-url="/login">
<concurrency-control error-if-maximum-exceeded="true" max-sessions="1" />
</session-management>
And i even added listener in web.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: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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- HTTP security configurations -->
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/resources/j_spring_security_check"
login-page="/login" default-target-url="/index"
authentication-success-handler-ref="myAuthenticationSuccessHandler"
authentication-failure-url="/login?login_error=t" />
<logout invalidate-session="true"
logout-url="/resources/j_spring_security_logout" success-handler-ref="myLogoutSuccessHandler"/>
<!-- Configure these elements to secure URIs in your application -->
<intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/member/**" access="isAuthenticated()" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
<session-management invalid-session-url="/login">
<concurrency-control error-if-maximum-exceeded="true"
max-sessions="1" />
</session-management>
</http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customDaoAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<beans:bean id="myAuthenticationSuccessHandler" class="com.test.connect.web.login.MyAuthenticationSuccessHandler"/>
<beans:bean id="myLogoutSuccessHandler" class="com.test.connect.web.login.MyLogoutSuccessHandler"/>
</beans:beans>
Based upon the configuration you provided, which includes a custom AuthenticationProvider, and the problem you are having I would guess that you are returning a custom UserDetails implementation that does not properly implement the equals and hashCode methods.
Please ensure that you have properly implemented equals and hashCode on any custom UserDetails implementation as these methods are used to look up if a user contains active sessions.
Just want to highlight here, make sure the equals and hashCode methods return is true. if the methods is not returning true it will not kill or terminate the existing session.

Resources