Spring security not authorizing user - java

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.

Related

Two ways to authenticate: CAS + SpringSecurity

my thought is to create a website where you can authenticate in two different ways: from a typical login (SpringSecurity) and from a CAS server.
A user reaching any protected page should be redirected to /login page, where Username and Password are needed to proceed further. Then we have a choice: clicking on "Login" button will authenticate the user ONLY for this site; otherwise clicking on "Login with CAS" will redirect the User on the Login of the CAS-server (or maybe, better: directly submit Username and Password to the CAS server) and then redirected to the web application.
Either from local or CAS, a user successfully logged in must have access to the site. How can I do this? For now, I only got the local authentication - and it's working.
spring-security.xml
<http auto-config="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/static/**" access="permitAll" />
<intercept-url pattern="/srv/**" access="permitAll" />
<intercept-url pattern="/admin" access="hasAnyRole('ROLE_ADMIN')" />
<intercept-url pattern="/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<...>
</http>
<form-login login-page='/login'
default-target-url="/home"
authentication-success-handler-ref="authSuccessHandler"
authentication-failure-url="/login?error=true" />
<logout logout-success-url="/login" />
<session-management invalid-session-url="/login">
<concurrency-control expired-url="/login" />
</session-management>
</http>
<authentication-manager>
<authentication-provider ref="authProvider"/>
</authentication-manager>
I'm not using SpringBoot; i got SpringSecurity 4.0.3 and Spring Framework 4.3.7

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!

Implementing of social media login into spring security

I am using Spring 3 and spring security. I'm integrating social accounts for instance: Facebook, Twitter, and Google. I'm using there javascript sdk version but my issue is I can register a user but I'm not sure how to authenticate them.
For example:
When user clicked on any of the Links(Facebook, Twitter, Google) new dialog box is opened after authenticated successfully I can get their basic profile details: email, id, name, images and I passed all this information to my controller using ajax which call service and dao to save user if user is not already registered.
Till here everything is working fine for me. I used user id and encrypt them using salt and save it into the database as a password(I'm not sure if this a correct way to deal with it or not) but now my confusion is how can I authenticate a user and allow them to login into the system.
My security.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- Configuration for master level user login -->
<http auto-config="true" use-expressions="true"
disable-url-rewriting="true">
<!-- <csrf /> -->
<headers>
<cache-control />
<content-type-options />
<hsts />
<frame-options />
<xss-protection />
</headers>
<!-- requires-channel="https" -->
<intercept-url pattern="/favicon.ico" access="permitAll" />
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/login/facebook-login*" access="permitAll" />
<intercept-url pattern="/validateUserCredentials*"
access="permitAll" />
<intercept-url pattern="/register*" access="permitAll" />
<intercept-url pattern="/activation*" access="permitAll" />
<intercept-url pattern="/restore*" access="permitAll" />
<intercept-url pattern="/resend*" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/license*"
access="hasAnyRole('${role.admin}', '${role.master}')" />
<intercept-url pattern="/**"
access="hasAnyRole('${role.admin}', '${role.master}', '${role.owner}', '${role.simple}')" />
<access-denied-handler error-page="/denied" />
<form-login login-page="/login" default-target-url="/logged"
authentication-failure-url="/loginfailed" login-processing-url="/j_spring_security_check" />
<logout logout-success-url="/login" invalidate-session="true"
delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE" />
<session-management session-fixation-protection="migrateSession">
<concurrency-control error-if-maximum-exceeded="true"
max-sessions="1" expired-url="/login" />
</session-management>
<remember-me token-validity-seconds="86400" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="saltSource" ref="saltSource" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<beans:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
<beans:bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="salt" />
</beans:bean>
<beans:bean id="userDetailsService" name="userAuthenticationProvider"
class="com.luffy.security.AuthenticationUserDetailService">
</beans:bean>
</beans:beans>
Any help will be appreciated. I did everything that I can to resolve this issue but I'm not able to figure out any reliable solution.
Let's say you are implementing Facebook Authentication.
Solution (1):
On successful response from Facebook you can call server API to update authentication table with facebook user credentials such as username/email and OAuth access_token.
$.post('api/fblogin', {access_token: accessToken}, function(response) {});
Solution (2):
Custom Security Handler. Here you can initiate your custom HTTP request to Facebook and upon successful completion you allow user to access the site.
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.*;
import org.springframework.stereotype.Component;
import com.restfb.*;;
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private #Autowired HttpServletRequest request;
#Override
public Authentication authenticate(Authentication authentication) {
String fb_access_token = String.valueOf(request.getParameter("fb_access_token"));
//fb user
Authentication auth = null;
try {
FacebookClient fbClient = new DefaultFacebookClient(fb_access_token);
User user = fbClient.fetchObject("me",com.restfb.types.User.class);
String email = user.getEmail();
String gender = user.getGender();
String pic = "http://graph.facebook.com/" + user.getId() + "/picture?type=normal";
//Your DB implementation
} catch (Exception e) {
throw new FacebookOAuthException("FB","OAuth",5002, null, null, "", "");
}
}
}
spring-security.xml
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customAuthenticationProvider" >
</authentication-provider>
</authentication-manager>
<bean id="customAuthenticationProvider" class="com.mi.common.CustomAuthenticationProvider"/>

Spring security. add restriction for user log in

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.

Categories