Spring security. add restriction for user log in - java

I have following spring security config:
<http auto-config="true" authentication-manager-ref="userAuthenticationManager">
<form-login login-page="/"
default-target-url="/member/personalAccount"
authentication-failure-url="/loginfailed" authentication-success-handler-ref="authSuccessHandler" />
<!-- <intercept-url pattern="/common/*" filters="none" /> -->
<intercept-url ..../>
<logout logout-url="/logout" logout-success-url="/" />
<port-mappings>
<port-mapping http="${http.port}" https="${https.port}"/>
</port-mappings>
</http>
....
<authentication-manager alias="userAuthenticationManager">
<!-- <authentication-provider user-service-ref="userSecurityService"> -->
<authentication-provider>
<password-encoder ref="encoder" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select email,password,prop_was_moderated from terminal_user where email = ?"
authorities-by-username-query="select email,user_role from terminal_user where email = ?" />
</authentication-provider>
</authentication-manager>
Now I want to add new column to terminal_user table.
This column called prop_confirmed
I want to achieve that only user who has prop_confirmed as true can be log in.
Can you help me to achieve it?

One way you could do it is to hardcode the prop_confirmed condition in users-by-username-query. That way if user is not confirmed, it will be as if they don't exist and the authentication will fail:
select email,password,prop_was_moderated from terminal_user
where email = ? AND prop_confirmed = TRUE
There are other (and possibly cleaner) solutions, such as customizing AuthenticationManager. Take a look at my SO answer regarding similar question for more detailed description of these options.

Related

Spring Security intercept URL access not working as expected

I am working on spring security namespace configuration.there is a problem in accessing some pages where intercept url denied to access that page.`
http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<http use-expressions="true">
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
<csrf disabled="true" />
<intercept-url pattern="/projectlist" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/projectboard/*" access="hasAnyRole('ROLE_OWNER','ROLE_MEMBER')" />
<access-denied-handler error-page="/access" />
<form-login login-page='/login' login-processing-url="/j_spring_security_check"
default-target-url="/dashboard" always-use-default-target="false"
authentication-failure-url="/login?error=true" username-parameter="username"
password-parameter="password" />
<logout logout-url="/logout" logout-success-url="/logoutSuccessful"
delete-cookies="JSESSIONID" invalidate-session="true" />
<remember-me key="myAppKey" token-validity-seconds="864000" />
</http>
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,enabled from user where username=?"
authorities-by-username-query="select * from ( (Select u.username,'ROLE_OWNER' user_role from user u inner join project_user pu on u.user_id = pu.user_id) UNION (Select u.username,'ROLE_MEMBER' user_role from user u inner join member m on u.user_id = m.user_id) UNION (Select ur.username,'ROLE_USER' user_role from user_roles ur inner join user u on u.username=ur.username)) as users where username =? group by user_role" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="10" />
</beans:bean>
`
This file is working when the user login and access the "/setting/" URL (that page is only accessible for owner not for member). but when the new user is register and directly access the page (even he is a owner), intercept url won't allow him to access the page. After he logout and again login to the system, he can able to access the "/setting/" URL page. I don't know ,where i was wrong.
any help appreciated.Thank you in advance.

Spring Security lgoin always redirecting to authentication failure URL

I am rather new to programming so please help me out a bit here.
I have configured Spring Security to fetch user details from the database and when I try to login with the following accounts:
user1 - password1
admin - password1
The authentication fails as it always redirect me to home.jsp/OPS=999 which is my login page. The user record exists in the database but I cannot seem to log in.
This is my security config xml file.
<http auto-config="true">
<form-login login-page='/home.jsp?OPS=9999' default-target-url='/secure/user.jsp' always-use-default-target='true' />
<logout logout-success-url="/home.jsp" logout-url="/j_spring_security_logout" />
</http>
<authentication-provider>
<jdbc-user-service data-source-ref="Application.DataSource2" users-by-username-query="select USERNAME, PASSWORD from USER where lower(USERNAME) = lower(?)"/>
</authentication-provider>
I am doing it without the authentication/authorities for now as the login is not working. What could be some of the possible reasons for the authentication failure? could database connection play a part? please help me out.
Thank you in advance!
I suggest to add another intercept-url. And it should look like this below:
<http auto-config="true"
use-expressions="true"
disable-url-rewriting="true">
<intercept-url pattern="/home.jsp**" access="isAnonymous()"/>
<intercept-url pattern="/secure/extreme/**" access="hasRole('ROLE_OPERATOR')" />
<intercept-url pattern="/secure/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login login-page='/home.jsp?OPS=9999' default-target-url='/secure/user.jsp' always-use-default-target='true' />
<logout logout-success-url="/home.jsp" logout-url="/j_spring_security_logout" />
</http>
Try setting authentication provider to authentication manager by creating a bean like..
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService" />
</authentication-manager>
<beans:bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="usersByUsernameQuery" value="select USERNAME, PASSWORD, 1 from USER where lower(USERNAME) = lower(?)"/>
<property name="authoritiesByUsernameQuery" value="SELECT USERNAME, ROLE as authorities FROM USER u, USER_ROLE ur, ROLE r WHERE u.ID = ur.USER_ID AND ur.ROLE_ID = r.ID AND lower(USERNAME) = lower(?)" />
<property name="dataSource" ref="Application.DataSource2" />
</beans:bean>
Realised that the users-by-username-query in the applicationContext-security xml file was missing a enabled column, basically spring security expects 3 columns from the statement and i was missing the enabled column.
so the correct sql statement should be:
"select USERNAME, PASSWORD, STATUS from USER where lower(USERNAME) = lower(?)"
status column is of type boolean. (1=enabled, 0=disabled)
Hope it will help someone out there :)
Thanks for all the help everyone!

Spring security not authorizing user

I'm new to Spring Security and I'm developing a web app which requires authentication and authorization using Spring Security 3.2, the authentication part is working fine but the authorization is not. Below is my spring security configuration xml snippet.
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder" />
<jdbc-user-service data-source-ref="myDataSource"
users-by-username-query=" SELECT email_address as username , password, enabled FROM users WHERE email_address = ? "
authorities-by-username-query=" SELECT u.email_address as username ,
r.role_name FROM users u
INNER JOIN user_roles ur
ON ur.user_id = u.user_id
INNER JOIN roles r
ON r.role_id = ur.role_id
WHERE u.email_address = ? "/>
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
<http pattern="/resources/**" security="none" />
<http auto-config="true" use-expressions="true" create-session="ifRequired">
<form-login login-page="/" default-target-url="/admin/dashboard"
authentication-failure-url="/login-error" always-use-default-target="true" />
<!-- Security zones -->
<intercept-url pattern="/" access="isAnonymous()" />
<intercept-url pattern="/admin*" access="hasRole('ROLE_ADMIN')" />
<session-management invalid-session-url="/"
session-fixation-protection="newSession">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</session-management>
<logout logout-success-url="/" delete-cookies="JSESSIONID"
invalidate-session="true" />
<access-denied-handler error-page="/403" />
</http>
With this configuration everything works fine apart from authorization. I have two users viz tim#abc.com (role=ADMIN) and bob#abc.com(role=USER), but when I try to login with bob#abc.com then also I'm able to view the admin/dashboard page which should not happen.
I've referred many tutorials and spring doc as well but not able to find the exact problem. Please help.
Change the pattern to "/admin/*"
<intercept-url access="hasRole('ROLE_ADMIN')" />
Your default-target-url="/admin/dashboard" seems to be confusing as for every user it will redirect to /admin/dashboard after login. You may get http UnAuthorized response when you login with bob#abc.com.

Spring security authentication using database

I am struggling with spring security authentication using database. Simply saying it doesn't work - i can't login on my user, it always redirects me to accessdenied.
application-security.xml
<http auto-config="true" use-expressions="true">
<csrf disabled="true"/>
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/accessdenied" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<form-login login-page="/login" default-target-url="/AddUser.html" authentication-failure-url="/accessdenied" />
<logout logout-url="/j_spring_security_logout" logout-success-url="/logout"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,enabled from user_authentication where username=?"
authorities-by-username-query="select u1.username, u2.role from user_authentication u1, user_authorization u2 where u1.user_id = u2.user_id and u1.username =?" />
</authentication-provider>
</authentication-manager>
I have user = 'abcd' with password 'abcd'. Database query select u1.username, u2.role from user_authentication u1, user_authorization u2 where u1.user_id = u2.user_id and u1.username ='abc' returns 'abcd' with 'ROLE_ADMIN'. My login form must be ok (everything was ok when i was using hardcoded username and password in my application-security.xml). Also datasource is fine - it works for CRUD operations. Any ideas what might be wrong?
In the form-login:
<form-login login-page="/login"
default-target-url="/AddUser.html"
authentication-failure-url="/accessdenied" />
you dont't have any parameters like:
username-parameter="username"
password-parameter="password"
So just add them:
<form-login login-page="/login"
default-target-url="/AddUser.html"
username-parameter="username"
password-parameter="password"
authentication-failure-url="/accessdenied" />

return 403 error if isAuthenticated() == false

I have this spring security configuration:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/home.jsp" access="permitAll" />
<intercept-url pattern="/loginFailed" access="permitAll" />
<intercept-url pattern="/logOut" access="permitAll" />
<intercept-url pattern="/*" access="isAuthenticated()" />
<form-login login-page="/home.jsp" default-target-url="/index"
authentication-failure-url="/loginFailed" />
<logout logout-success-url="/logOut"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="N_a" password="12" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
If I type url, that need access="isAuthenticated() I redirect to home.jsp.
I want to see 403 error.
How to change it ?
You are using a form-based login and as such, when not authenticated, you will be prompted with the login-page. This is what you have configured and this is how, by default, Spring Security works.
If you want to override this you need to explicitly configure an AuthenticationEntryPoint to be precise the Http403ForbiddenEntryPoint. This basically always gives a 403 if someone isn't authenticated or doesn't have access. This disables the ability to be prompted with a login-form to give a user the change to login after all.
<beans:bean id="entryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<http auto-config="true" use-expressions="true" entry-point-ref="entryPoint">
<!-- Your other elements here -->
</http>
use access-denied-handler tag in http tag.
http://www.mkyong.com/spring-security/customize-http-403-access-denied-page-in-spring-security/
or use access-denied-page property.
<http auto-config="true" access-denied-page="/403"></http>

Categories