I have Java Restful web service with Spring Security, JAX-RS Jersey. I use #PreAuthorize annotations for method security, but it doesn't work.
I have method, which use annotation #PreAuthorize("hasRole('ROLE_ADMIN')"), but users with ROLE_USER, also have access to this method.
Can anybody help me?
Spring version
<spring.version>3.2.8.RELEASE</spring.version>
<spring.security.version>3.2.3.RELEASE</spring.security.version>
My spring-security-context.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:security="http://www.springframework.org/schema/security"
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/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<http use-expressions="true" auto-config="true">
<intercept-url pattern="/rest/users/list" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/rest/users/add" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/rest/users/update" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/rest/users/**" method="DELETE" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/rest/users/get/**" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/rest/orders/**" access="hasAnyRole('ROLE_ADMIN', 'ROLE_USER')"/>
<logout logout-url="/logout"/>
</http>
<security:global-method-security secured-annotations="enabled"
pre-post-annotations="enabled"/>
<beans:bean id="customUserService" class="com.bankproject.services.CustomUserDetailService"/>
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_USER"/>
<user name="admin" password="admin" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="orderDAO" class="com.bankproject.DAO.Impl.OrderOutputDAOImpl"/>
<beans:bean id="orderManager" class="com.bankproject.services.OrderService"/>
My OutputOrderDAOImpl.java
public class OrderOutputDAOImpl implements OrderOutputDAO {
#Override
#PreAuthorize("hasRole('ROLE_ADMIN')")
public List<OrderOutputObject> getOrdersByUsername(String username) throws SQLException {
List<OrderObject> orders = orderDAO.getOrdersByUsername(username);
return getOutputOrders(orders);
}
}
My OrderService.java
#Path("/orders")
public class OrderService {
#GET
#Path("/{username}")
#Produces(MediaType.APPLICATION_JSON)
public List<OrderOutputObject> getOrdersForUser(#PathParam("username") String username){
List<OrderOutputObject> orders = new ArrayList<OrderOutputObject>();
try{
orders = orderOutputDAO.getOrdersByUsername(username);
}catch (Exception e){
e.printStackTrace();
}
return orders;
}
}
Related
The project structure is
Actually, I am integeration the Spring Security in my Spring MVC project. Simpley I want to do is to add the LoginDAO in the customAuthenticationProvider class. But I am getting this exception.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.wusuq.dao.LoginDAO' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 93 more
The CustomAuthenticationProvider class code is
package com.wusuq.security;
import java.util.ArrayList;
import java.util.List;
import com.wusuq.dao.LoginDAO;
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Autowired
private LoginDAO login;
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
String userName = authentication.getName();
String password = authentication.getCredentials().toString();
if (authorizedUser(userName, password))
{
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMINN"));
Authentication auth = new UsernamePasswordAuthenticationToken(userName, password, grantedAuths);
System.out.println(auth.getAuthorities());
return auth;
}
else
{
throw new AuthenticationCredentialsNotFoundException("Invalid Credentials!");
}
}
private boolean authorizedUser(String userName, String password)
{
System.out.println("username is :" + userName+" and password is "+password );
if("Chandan".equals(userName) && "Chandan".equals(password))
return true;
return false;
}
#Override
public boolean supports(Class<?> authentication)
{
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
public LoginDAO getLogin() {
return login;
}
public void setLogin(LoginDAO login) {
this.login = login;
}
}
LoginDAO class code is
#Transactional
public class LoginDAO {
#Autowired
private SessionFactory sessionFactory;
Session session = null;
Criteria criteria = null;
Transaction tx = null;
public LoginDAO() {
super();
}
}
secirity-config.xml file
<?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-4.0.xsd
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">
<sec:http auto-config="true" use-expressions="true">
<sec:form-login login-page="/"
login-processing-url="/authenticateUser"
authentication-failure-url="/login" username-parameter="username"
password-parameter="password"
default-target-url="/menu"
always-use-default-target="true"
/>
<sec:access-denied-handler error-page="/jsp/403.jsp" />
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/JS/**" access="permitAll" />
<sec:intercept-url pattern="/img/**" access="permitAll" />
<!-- <sec:intercept-url pattern="/JS/**" access="permitAll" /> -->
<sec:intercept-url pattern="/**" access="hasAuthority('ROLE_ADMINN')" />
<sec:session-management invalid-session-url="/login" />
<sec:logout delete-cookies="JSESSIONID" logout-url="/logout" />
</sec:http>
<context:component-scan base-package="com.wusuq.security" />
<sec:authentication-manager>
<authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
</beans:beans>
Can some please guide me how to fix this issue I want to Autowire the LoginDAO in CustomAuthentionProvider class to authenticate the user from Databbase. Help will be appreciated. Thanks
After upgrading some dependencies in our maven project to make the project run with jdk11 containers, I had to update from SpringSecurity 4.0.x to 4.2.x. So I wanted to give it a shot and convert the messy XML to a proper Java-config.
the xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd" default-autowire="byName">
<!-- Spring Security Settings -->
<security:global-method-security pre-post-annotations="enabled"></security:global-method-security>
<security:http-firewall ref="defaultHttpFirewall"/>
<security:http pattern="/api/**" security="none" />
<security:http pattern="/prometheus/**" security="none" />
<security:http entry-point-ref="restEntryPoint" pattern="/login*">
<security:intercept-url pattern="/login*"/>
<security:custom-filter ref="managerRequestRedirectFilter" before="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/login/sso*">
<security:intercept-url pattern="/login/sso*"/>
<security:custom-filter ref="managerRequestRedirectFilter" before="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http pattern="/authenticate" security="none" />
<security:http pattern="/resources/bootstrap/**" security="none" />
<security:http pattern="/resources/css/**" security="none" />
<security:http pattern="/resources/js/**" security="none" />
<security:http pattern="/WEB-INF/views/login.jsp*" security="none" />
<security:http pattern="/databaseStatus" security="none" />
<security:http pattern="/module/**" security="none" />
<security:http pattern="/myarea/**" security="none" />
<security:http pattern="/ajax/**" security="none" />
<security:http pattern="/logout/sso" security="none" />
<security:http pattern="/download/**" security="none" />
<bean id="managerRequestRedirectFilter" class="com.pany.managertemplate.authentication.service.ManagerRequestRedirectFilter"/>
<!-- Spring Security Kerberos Settings -->
<bean id="authenticationResultFilter" class="com.pany.managertemplate.authentication.service.ManagerAuthenticationResultFilter"/>
<!-- rest -->
<bean id="restAuthenticationProcessingFilter" class=" com.pany.managertemplate.authentication.service.RestAuthenticationProcessingFilter" />
<bean id="restEntryPoint" class="com.pany.managertemplate.authentication.service.RestAuthenticationEntryPoint" />
<security:http entry-point-ref="restEntryPoint" pattern="/rest/**">
<security:intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/hooks/**">
<security:intercept-url pattern="/hooks/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/get/**">
<security:intercept-url pattern="/get/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/hook/**">
<security:intercept-url pattern="/hook/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/hookhistories/**">
<security:intercept-url pattern="/hookhistories/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/hookcalls/**">
<security:intercept-url pattern="/hookcalls/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<security:http entry-point-ref="restEntryPoint" pattern="/hookversions/**">
<security:intercept-url pattern="/hookversions/**" access="hasRole('ROLE_USER')" />
<security:custom-filter ref="restAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:csrf disabled="true"/>
</security:http>
<!-- -->
<bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
<bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/login"/>
</bean>
<security:http entry-point-ref="spnegoEntryPoint">
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<security:custom-filter ref="managerRequestRedirectFilter" before="BASIC_AUTH_FILTER" />
<security:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:custom-filter ref="authenticationResultFilter" after="BASIC_AUTH_FILTER" />
<security:session-management session-fixation-protection="newSession">
<security:concurrency-control max-sessions="1" expired-url="/login"/>
</security:session-management>
<security:csrf disabled="true"/>
</security:http>
<bean id="spnegoEntryPoint" class="com.pany.managertemplate.authentication.service.ManagerAuthenticationEntryPoint" />
<bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="useForward" value="true"/>
<property name="defaultFailureUrl" value="/login"/>
</bean>
<bean id="authenticationSuccessHandler" class="com.pany.managertemplate.authentication.service.ManagerAuthenticationSuccessHandler" />
<bean id="spnegoAuthenticationProcessingFilter" class="com.pany.managertemplate.authentication.service.ManagerSpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="failureHandler" ref="simpleUrlAuthenticationFailureHandler"/>
<property name="successHandler" ref="authenticationSuccessHandler"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="kerberosServiceAuthenticationProvider" />
<security:authentication-provider ref="kerberosAuthenticationProvider"/>
</security:authentication-manager>
<bean id="kerberosAuthenticationProvider"
class="org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider">
<property name="kerberosClient">
<bean class="org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient">
<property name="debug" value="false"/>
</bean>
</property>
<property name="userDetailsService" ref="kerberosUserDetailsService"/>
</bean>
<bean id="kerberosServiceAuthenticationProvider" class="org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean class="org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator">
<property name="servicePrincipal"
value="HTTP/an.URL"/>
<property name="keyTabLocation"
value="file:/etc/krb5.keytab"/>
<property name="debug" value="false" />
</bean>
</property>
<property name="userDetailsService" ref="kerberosUserDetailsService" />
</bean>
<bean class="org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig">
<property name="debug" value="false" />
<property name="krbConfLocation" value="/etc/krb5.conf"/>
</bean>
<bean id="kerberosUserDetailsService" class="com.pany.managertemplate.authentication.service.KerberosUserDetailsService"/>
</beans>
and the try of a config I used:
package com.pany.managertemplate.configuration.service;
import java.net.MalformedURLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider;
import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider;
import org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator;
import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
import com.pany.managertemplate.authentication.service.KerberosUserDetailsService;
import com.pany.managertemplate.authentication.service.ManagerAuthenticationEntryPoint;
import com.pany.managertemplate.authentication.service.ManagerAuthenticationResultFilter;
import com.pany.managertemplate.authentication.service.ManagerAuthenticationSuccessHandler;
import com.pany.managertemplate.authentication.service.ManagerRequestRedirectFilter;
import com.pany.managertemplate.authentication.service.ManagerSpnegoAuthenticationProcessingFilter;
import com.pany.managertemplate.authentication.service.RestAuthenticationEntryPoint;
import com.pany.managertemplate.authentication.service.RestAuthenticationProcessingFilter;
#Configuration
#Order(1)
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
#Configuration
#Order(3)
public static class GlobalSecurity extends WebSecurityConfigurerAdapter
{
#Autowired
#Qualifier("authenticationResultFilter")
private ManagerAuthenticationResultFilter authenticationResultFilter;
#Autowired
private KerberosAuthenticationProvider kerberosAuthenticationProvider;
#Autowired
private KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider;
#Autowired
private ManagerRequestRedirectFilter managerRequestRedirectFilter;
#Autowired
#Qualifier("restEntryPoint")
private RestAuthenticationEntryPoint restEntryPoint;
#Autowired
private SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter;
#Autowired
#Qualifier("spnegoEntryPoint")
private ManagerAuthenticationEntryPoint spnegoEntryPoint;
#Bean(BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
#Override
protected void configure(final AuthenticationManagerBuilder authManagerBuilder) throws Exception
{
authManagerBuilder.authenticationProvider(this.kerberosServiceAuthenticationProvider);
authManagerBuilder.authenticationProvider(this.kerberosAuthenticationProvider);
}
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http.csrf().disable();
http.authorizeRequests().antMatchers(HttpMethod.GET, "/health").permitAll();
http.authorizeRequests().antMatchers("/authenticate").permitAll();
http.authorizeRequests().antMatchers("/resources/bootstrap/**").permitAll();
http.authorizeRequests().antMatchers("/resources/css/**").permitAll();
http.authorizeRequests().antMatchers("/resources/js/**").permitAll();
http.authorizeRequests().antMatchers("/WEB-INF/views/login.jsp*").permitAll();
http.authorizeRequests().antMatchers("/databaseStatus").permitAll();
http.authorizeRequests().antMatchers("/module/**").permitAll();
http.authorizeRequests().antMatchers("/myarea/**").permitAll();
http.authorizeRequests().antMatchers("/ajax/**").permitAll();
http.authorizeRequests().antMatchers("/logout/sso").permitAll();
http.authorizeRequests().antMatchers("/download/**").permitAll();
http.authorizeRequests().antMatchers("/api/**").permitAll();
http.authorizeRequests().antMatchers("/prometheus/**").permitAll();
http.authorizeRequests().antMatchers("/**").hasRole("USER");
http.exceptionHandling().authenticationEntryPoint(this.spnegoEntryPoint);
http.addFilterBefore(this.managerRequestRedirectFilter, BasicAuthenticationFilter.class);
http.addFilterAt(this.spnegoAuthenticationProcessingFilter, BasicAuthenticationFilter.class);
http.addFilterAfter(this.managerRequestRedirectFilter, BasicAuthenticationFilter.class);
}
}
#Configuration
#Order(1)
public static class LoginSecurity extends WebSecurityConfigurerAdapter
{
#Autowired
private KerberosAuthenticationProvider kerberosAuthenticationProvider;
#Autowired
private KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider;
#Autowired
private ManagerRequestRedirectFilter managerRequestRedirectFilter;
#Autowired
#Qualifier("restEntryPoint")
private RestAuthenticationEntryPoint restEntryPoint;
#Override
protected void configure(final AuthenticationManagerBuilder authManagerBuilder) throws Exception
{
authManagerBuilder.authenticationProvider(this.kerberosServiceAuthenticationProvider);
authManagerBuilder.authenticationProvider(this.kerberosAuthenticationProvider);
}
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http.csrf().disable();
http.antMatcher("/login*").antMatcher("/login/sso*");
http.authorizeRequests().anyRequest().permitAll();
http.exceptionHandling().authenticationEntryPoint(this.restEntryPoint);
http.addFilterBefore(this.managerRequestRedirectFilter, BasicAuthenticationFilter.class);
http.sessionManagement().sessionFixation().newSession().maximumSessions(1).expiredUrl("/login");
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().loginPage("/login");
}
}
#Configuration
#Order(2)
public static class RestSecurity extends WebSecurityConfigurerAdapter
{
#Autowired
#Qualifier("authenticationResultFilter")
private ManagerAuthenticationResultFilter authenticationResultFilter;
#Autowired
private KerberosAuthenticationProvider kerberosAuthenticationProvider;
#Autowired
private KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider;
#Autowired
private RestAuthenticationProcessingFilter restAuthenticationProcessingFilter;
#Autowired
#Qualifier("restEntryPoint")
private RestAuthenticationEntryPoint restEntryPoint;
#Override
protected void configure(final AuthenticationManagerBuilder authManagerBuilder) throws Exception
{
authManagerBuilder.authenticationProvider(this.kerberosServiceAuthenticationProvider);
authManagerBuilder.authenticationProvider(this.kerberosAuthenticationProvider);
}
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http.csrf().disable();
http.antMatcher("/rest/**").antMatcher("/hooks/**").antMatcher("/get/**").antMatcher("/hook/**").antMatcher("/hookhistories/**")
.antMatcher("/hookcalls/**").antMatcher("/hookversions/**");
http.authorizeRequests().anyRequest().permitAll();
http.exceptionHandling().authenticationEntryPoint(this.restEntryPoint);
http.addFilterAt(this.restAuthenticationProcessingFilter, BasicAuthenticationFilter.class);
http.addFilterAfter(this.authenticationResultFilter, BasicAuthenticationFilter.class);
}
}
#Autowired
#Qualifier("authenticationResultFilter")
private ManagerAuthenticationResultFilter authenticationResultFilter;
#Autowired
#Qualifier("restEntryPoint")
private RestAuthenticationEntryPoint restEntryPoint;
#Autowired
#Qualifier("spnegoEntryPoint")
private ManagerAuthenticationEntryPoint spnegoEntryPoint;
#Bean
public AccessDeniedHandlerImpl accessDeniedHandler()
{
AccessDeniedHandlerImpl accessDeniedHandlerImpl = new AccessDeniedHandlerImpl();
accessDeniedHandlerImpl.setErrorPage("/login");
return accessDeniedHandlerImpl;
}
#Override
public void configure(final WebSecurity web) throws Exception
{
// though StrictHttpFirewall is advised
super.configure(web);
web.httpFirewall(this.defaultHttpFirewall());
}
#Bean
public HttpFirewall defaultHttpFirewall()
{
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
#Bean
public GlobalSunJaasKerberosConfig globalSunJaasKerberosConfig()
{
GlobalSunJaasKerberosConfig globalSunJaasKerberosConfig = new GlobalSunJaasKerberosConfig();
globalSunJaasKerberosConfig.setDebug(false);
globalSunJaasKerberosConfig.setKrbConfLocation("/etc/krb5.conf");
return globalSunJaasKerberosConfig;
}
#Bean("kerberosAuthenticationProvider")
public KerberosAuthenticationProvider kerberosAuthenticationProvider(#Qualifier("kerberosClient") final SunJaasKerberosClient kerberosClient,
final KerberosUserDetailsService kerberosUserDetailsService)
{
KerberosAuthenticationProvider kerberosAuthenticationProvider = new KerberosAuthenticationProvider();
kerberosAuthenticationProvider.setKerberosClient(kerberosClient);
kerberosAuthenticationProvider.setUserDetailsService(kerberosUserDetailsService);
return kerberosAuthenticationProvider;
}
#Bean("kerberosServiceAuthenticationProvider")
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider(final KerberosUserDetailsService kerberosUserDetailsService,
#Qualifier("ticketValidator") final SunJaasKerberosTicketValidator ticketValidator)
{
KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider = new KerberosServiceAuthenticationProvider();
kerberosServiceAuthenticationProvider.setUserDetailsService(kerberosUserDetailsService);
kerberosServiceAuthenticationProvider.setTicketValidator(ticketValidator);
return kerberosServiceAuthenticationProvider;
}
#Bean
public KerberosUserDetailsService kerberosUserDetailsService()
{
return new KerberosUserDetailsService();
}
#Bean("spnegoEntryPoint")
public ManagerAuthenticationEntryPoint managerAuthenticationEntryPoint()
{
return new ManagerAuthenticationEntryPoint();
}
#Bean("authenticationResultFilter")
public ManagerAuthenticationResultFilter managerAuthenticationResultFilter()
{
return new ManagerAuthenticationResultFilter();
}
#Bean("authenticationSuccessHandler")
public ManagerAuthenticationSuccessHandler managerAuthenticationSuccessHandler()
{
return new ManagerAuthenticationSuccessHandler();
}
#Bean
public ManagerRequestRedirectFilter managerRequestRedirectFilter()
{
return new ManagerRequestRedirectFilter();
}
#Bean("spnegoAuthenticationProcessingFilter")
public ManagerSpnegoAuthenticationProcessingFilter managerSpnegoAuthenticationProcessingFilter(final AuthenticationManager authenticationManager,
final SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler,
#Qualifier("authenticationSuccessHandler") final AuthenticationSuccessHandler authenticationSuccessHandler)
{
ManagerSpnegoAuthenticationProcessingFilter managerSpnegoAuthenticationProcessingFilter = new ManagerSpnegoAuthenticationProcessingFilter();
managerSpnegoAuthenticationProcessingFilter.setAuthenticationManager(authenticationManager);
managerSpnegoAuthenticationProcessingFilter.setFailureHandler(simpleUrlAuthenticationFailureHandler);
managerSpnegoAuthenticationProcessingFilter.setSuccessHandler(authenticationSuccessHandler);
return managerSpnegoAuthenticationProcessingFilter;
}
#Bean("restEntryPoint")
public RestAuthenticationEntryPoint restAuthenticationEntryPoint()
{
return new RestAuthenticationEntryPoint();
}
#Bean
public RestAuthenticationProcessingFilter restAuthenticationProcessingFilter()
{
return new RestAuthenticationProcessingFilter();
}
#Bean("simpleUrlAuthenticationFailureHandler")
public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler()
{
SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();
simpleUrlAuthenticationFailureHandler.setUseForward(true);
simpleUrlAuthenticationFailureHandler.setDefaultFailureUrl("/login");
return simpleUrlAuthenticationFailureHandler;
}
#Bean
public SunJaasKerberosClient sunJaasKerberosClient()
{
SunJaasKerberosClient sunJaasKerberosClient = new SunJaasKerberosClient();
sunJaasKerberosClient.setDebug(false);
return sunJaasKerberosClient;
}
#Bean("ticketValidator")
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() throws MalformedURLException
{
SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator = new SunJaasKerberosTicketValidator();
sunJaasKerberosTicketValidator.setServicePrincipal("HTTP/an.URL");
Resource keyTabFile = new UrlResource("file:/etc/krb5.keytab");
sunJaasKerberosTicketValidator.setKeyTabLocation(keyTabFile);
sunJaasKerberosTicketValidator.setDebug(false);
return sunJaasKerberosTicketValidator;
}
}
Login via /login works fine, permissions working inside the applications webinterface.
The problem I encountered is the part for the server-to-server communication via REST.
Sending the proper credentials like used to now just returns the login page instead of the requested resource - this is the point where I am stuck.
I feel like, the config is too complex and confusing at some points because of several entrypoints. but that was what I read in the offical documentation. Or is there an easier way and I am just thinking too complex? In short Java-Config behaves not like the Java-Config, and I can't see why so far.
I take this error when set authenticationFailureHandler: setAuthenticationFailureHandler(authenticationFailureHandler);
java.lang.IllegalArgumentException: failureHandler cannot be null at
org.springframework.util.Assert.notNull(Assert.java:193) at
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.setAuthenticationFailureHandler(AbstractAuthenticationProcessingFilter.java:448)
fragment web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
security.xml
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="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">
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled" jsr250-annotations="enabled"/>
<http use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint" authentication-manager-ref="authenticationManager" >
<csrf disabled="true"/>
<custom-filter before="FORM_LOGIN_FILTER" ref="authenticationFilter" />
<intercept-url pattern="/public_home/**" access="permitAll"/>
<intercept-url pattern="/js/**" access="permitAll"/>
<intercept-url pattern="/css/**" access="permitAll"/>
<intercept-url pattern="/image/**" access="permitAll"/>
<intercept-url pattern="/resources/**" access="permitAll"/>
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
</http>
<authentication-manager/>
<b:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<b:constructor-arg name="loginFormUrl" value="/public_home"/>
</b:bean>
<b:bean id="authenticationManager" class="n4.security.CustomAuthenticationManager">
</b:bean>
<b:bean id="authenticationFilter" class="n4.security.CustomAuthenticationFilter">
<b:property name="filterProcessesUrl" value="/j_spring_security_check" />
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
<b:property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
</b:bean>
<b:bean name="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<b:property name="defaultTargetUrl" value="/home"></b:property>
<b:property name="alwaysUseDefaultTargetUrl" value="true"></b:property>
<b:property name="useReferer" value="true"></b:property>
</b:bean>
<b:bean name="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<b:property name="defaultFailureUrl" value="/public_home/loginfailed"></b:property>
</b:bean>
</b:beans>
CustomAuthenticationFilter
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private SimpleUrlAuthenticationFailureHandler authenticationFailureHandler;
#Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
setAuthenticationManager(authenticationManager);
setAuthenticationFailureHandler(authenticationFailureHandler);
return super.attemptAuthentication(request, response);
}
}
CustomAuthenticationManager
public class CustomAuthenticationManager implements AuthenticationManager{
#Autowired
private UtenteDao utenteDao;
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String)authentication.getPrincipal();
String password = (String)authentication.getCredentials();
Utente utente = utenteDao.login(username, password);
AuthUserDetail principal = new AuthUserDetail(utente);
return principal.refreshGrantAuthority();
}
}
I am having troubles when trying to log in my application using Spring Security, no matter what I do it always redirects me to the JSP I use for non-authorized access.
On the configuration of security-config.xml I tried hasRole('ROLE_USER') and permitAll and none of them worked either.
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: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>
<intercept-url pattern="/user/**" access="hasAnyRole('ROLE_USER') />
<form-login login-page="/customLogin.jsp"
login-processing-url="/appLogin"
username-parameter="app_username"
password-parameter="app_password"
default-target-url="/user/home" />
<logout
logout-url="/appLogout"
logout-success-url="/customLogin.jsp" />
<access-denied-handler error-page="/user/error" />
</http>
<beans:bean name="bcryptEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<beans:bean name="myAppUserDetailsService"
class="com.prh.tracking.services.impl.UserDetailsServiceImpl" />
<beans:bean name="userService"
class="com.prh.tracking.services.impl.UserServiceImpl" />
<authentication-manager>
<authentication-provider
user-service-ref="myAppUserDetailsService">
<password-encoder ref="bcryptEncoder" />
</authentication-provider>
</authentication-manager>
<global-method-security
secured-annotations="enabled" />
</beans:beans>
UserController.java
#Controller
#RequestMapping("/user")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value="/home")
public String home(ModelMap model, Authentication authentication) {
authentication.getPrincipal();
model.addAttribute("user", userService.getUser(authentication.getName()));
return "user-info";
}
#RequestMapping(value="/error")
public String error() {
return "access-denied";
}
}
UserDetailsServiceImpl.java
#Service
public class UserDetailsServiceImpl implements UserDetailsService{
#Autowired
private UserDAO userDAO;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity user = userDAO.getUser(username);
GrantedAuthority authority = new SimpleGrantedAuthority(user.getRole());
UserDetails userDetails = (UserDetails)new User(user.getName(), user.getPassword(), Arrays.asList(authority));
return userDetails;
}
}
This is what I have in my Database:
When you set access to permitAll, you should not be even asked for credential and UserDetailsServiceImpl would not be consulted at all.
You may need to enable web security expressions like this:
<http use-expressions="true">
See
https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html#el-access-web
#Component("MyAuthFilter")
public class MyAuthFilter extends UsernamePasswordAuthenticationFilter {
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
...
}}
my spring-security:
<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-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/courses*" access="hasRole('ROLE_USER')" />
<custom-filter before="FORM_LOGIN_FILTER" ref="MyAuthFilter" />
<form-login
login-page="/login"
default-target-url="/courses"
authentication-failure-url="/login?error"
username-parameter="loginField"
password-parameter="passwordField" />
<csrf disabled="true" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="ars" password="1234" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
i'm trying to add my custom filter in spring security, but on startup i get an error that authenticationManager must be specified. Can someone have a look?
Try adding an #Autowired to setter of AuthenticationManager
#Autowired
#Qualifier("authenticationManager")
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
UPDATE
Add alias="authenticationManager" for your Authentication Manager
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="ars" password="1234" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>