最近我一直在尝试将Spring Security集成到我的REST API中。我发现以下SO回答Login/logout in REST with Spring 3并尝试在我的项目中实现它。
在修补了一些小事后,我似乎遇到了一些问题。
在我的intercept-url
即使我设置了对permitAll
的访问权限,我也会收到以下错误:
HTTP状态500 - 在SecurityContext中找不到Authentication对象
localhost:8080/Login
尝试登录时,没有弹出窗口,我收到404
。 这是我的代码:
web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>name</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:spring-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.trackmygymlife.webservices</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
spring-security.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
classpath:org/springframework/beans/factory/xml/spring-beans-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/login" filters="sif,wsFilter" />
<sec:filter-chain pattern="/logout" filters="sif,logoutFilter" />
<sec:filter-chain pattern="/rest/**" filters="sif,fsi" />
</list>
</constructor-arg>
</bean>
<bean id="sif"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<bean id="wsFilter" class="com.trackmygymlife.security.UserAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="authSuccessHandler" />
<property name="passwordParameter" value="pass"></property>
<property name="usernameParameter" value="user"></property>
<property name="postOnly" value="false"></property>
</bean>
<bean id="authSuccessHandler"
class="com.trackmygymlife.security.AuthenticationSuccessHandler"></bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider user-service-ref="userService" >
<sec:password-encoder hash="bcrypt"></sec:password-encoder>
</sec:authentication-provider>
</sec:authentication-manager>
<bean id="authenticationProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userService" />
</bean>
</property>
</bean>
<bean id="userService"
class="com.trackmygymlife.serviceimpl.TrackMyGymLifeUserService" />
<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg index="0" value="/">
</constructor-arg>
<constructor-arg index="1">
<bean
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</constructor-arg>
</bean>
<bean id="httpRequestAccessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<constructor-arg>
<list>
<ref bean="roleVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter "/>
</list>
</constructor-arg>
<!-- <property name="decisionVoters"> -->
<!-- <list> -->
<!-- </list> -->
<!-- </property> -->
</bean>
<bean id="roleVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter" />
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
<bean id="fsi"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')" />
</sec:filter-security-metadata-source>
</property>
</bean>
</beans>
AuthenticationSuccessHandler
:
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
@PostConstruct
public void afterPropertiesSet() {
setRedirectStrategy(new NoRedirectStrategy());
}
protected class NoRedirectStrategy implements RedirectStrategy {
@Override
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
throws IOException {
}
}
UserAuthenticationFilter
:
public class UserAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return (StringUtils.hasText(obtainUsername(request)) && StringUtils.hasText(obtainPassword(request)));
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
}
任何帮助都将不胜感激。