Spring Security: method is not secured with #PreAuthorize annotation - java

I would like to secure method in my managed session bean for specific role "ROLE_ADMIN"
config(applicationContext-security.xml):
<global-method-security pre-post-annotations="enabled" jsr250-annotations="enabled" secured-annotations="enabled"/>
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()"/>
<intercept-url pattern="/**" access="permitAll()"/>
<form-login
login-processing-url="/j_spring_security_check"
login-page="/login.jsf"
default-target-url="/main.jsf"
authentication-failure-url="/login.jsf" />
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false" />
</session-management>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="user1" password="user1" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
bean's secured method:
#PreAuthorize("hasRole('ROLE_ADMIN')")
public String buy() {
...
}
When I logged in under user1 or as anonym and click "buy" button on web-page, it still redirected to the next page.
I expect that some access denied exception occurred, and it doesn't.

Remember to enable method level security on your applicationContext-security.xml:
<sec:global-method-security secured-annotations="enabled" />
If, insted you will use Pre or Post annotations, use:
<security:global-method-security pre-post-annotations="enabled"/>
For more on this, see:
http://forum.springsource.org/showthread.php?t=77862
Note: For annotations from jsr-250:
<sec:global-method-security jsr250-annotations="enabled" />

Related

Access to the specified resource has been forbidden

I use spring Security. I'm trying to redirect from profile.jsp. And have
Access to the specified resource has been forbidden.
So, as i understand it's because of access failure somewhere. Page i want redirect to is also profile.jsp. So, i change options and i want to reload page. But have an exception
I've watched many similar on other topics, but still cant resolve
spring configuration
<http auto-config="true">
<intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
<intercept-url pattern="/chat" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/profile" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<form-login login-page="/login" default-target-url="/chat" authentication-failure-url="/login?error"
username-parameter="username" password-parameter="password"/>
<logout logout-success-url="/login?logout"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsServiceImpl">
<password-encoder ref="encoder"></password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="userDetailsServiceImpl"
class="com.chat.my.service.UserDetailsServiceImpl"></beans:bean>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11"/>
</beans:bean>
Try to add
<intercept-url pattern="/login*" access="isAnonymous()" />
Could be that your login page also expect to be authenticated because of your
<intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>

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 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 Pre authentication success handler

I have a web app where you can login with form-login or you can be pre-authenticated and be logged in like that. Both method work well but I only can find way to use a success handler with the form-login using the authentication-success-handler-ref property.
My question is, how can I call the success handler "mySuccessHandler" for the PRE_AUTH_FILTER in my security-app-context? I would guess I can call it as a property or something under the PreAuthenticatedProcessingFilter, preauthAuthProvider or the custom-filter.
Just need to go to different pages if the user has the role Teacher or Student.
<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.2.xsd">
<http pattern="/**" use-expressions="true" create-session="always">
<intercept-url pattern="/login.jsp*" access="permitAll" />
<intercept-url pattern="/**/ErrorPages/**" access="permitAll" />
<intercept-url pattern="/**/Students/**" access="hasAnyRole('STUDENT, TEACHER')" />
<intercept-url pattern="/**/Teacher/**" access="hasRole('TEACHER')" />
<intercept-url pattern="/**/Login/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**/Js/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**/Css/**" access="permitAll" />
<intercept-url pattern="/**/Img/**" access="permitAll" />
<intercept-url pattern="/**/api/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="denyAll" />
<custom-filter position="PRE_AUTH_FILTER" ref="PreAuthenticatedProcessingFilter" />
<access-denied-handler
<form-login
username-parameter="idnumber"
password-parameter="password" login-processing-url="/athuga_innskraningu"
login-page='/login.jsp'
authentication-failure-handler-ref="myAuthErrorHandler"
authentication-success-handler-ref="mySuccessHandler"
always-use-default-target='true'
authentication-failure-url="/login.jsp?login_error=true"/>
<logout logout-url="/utskra/" logout-success-url="/login.jsp"/>
</http>
<beans:bean id="mySuccessHandler" class="is.inna.rest.login.AuthenticationSuccess"/>
<beans:bean id="myAuthErrorHandler" class="is.inna.rest.login.AuthenticationFailure"/>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<beans:bean name="myUserDetailsService" class="is.inna.rest.login.UserDetailServiceLogin" />
<beans:bean id="userDetailsServiceWrapper" class="is.inna.rest.login.UserDetailServicePreAuth" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
<authentication-provider ref="preauthAuthProvider" />
</authentication-manager>
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceWrapper"/>
</beans:bean>
<beans:bean id="PreAuthenticatedProcessingFilter" class="is.inna.rest.login.PreAuthenticatedProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
Your requirement is to redirect user to different pages depending on the role. You can do this using authentication success handler also. Refer the sample success handler class I have written. You always have access to Authentication object in the overridden onAuthenticationSuccess method. You can get the authorities and role of logged in user and depending upon it, you can always redirect user to appropriate page.
Hope this helps.

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