我正在开发一些休息应用程序,并且在弹簧安全性配置方面存在问题。
在我的其他应用程序中帮助我获取spring security 4的xml配置。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<import resource="classpath*:securityServicesContext.xml"/>
<import resource="classpath*:businessServicesContext.xml"/>
<sec:http pattern="/rest/**" create-session="stateless" auto-config="false" entry-point-ref="unauthorizedEntryPoint">
<sec:expression-handler ref="webSecurityExpressionHandler"/>
<sec:custom-filter ref="customTokenAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
<sec:intercept-url pattern="/rest/login" access="permitAll"/>
<sec:intercept-url pattern="/**" access="hasRole('USER')"/>
<sec:csrf disabled="true"/>
</sec:http>
<sec:authentication-manager id="authenticationManager">
<sec:authentication-provider ref="daoAuthenticationProvider"/>
</sec:authentication-manager>
<bean id="unauthorizedEntryPoint" class="com.itechart.security.web.security.UnauthorizedEntryPoint"/>
<bean id="customTokenAuthenticationFilter"
class="com.itechart.security.web.security.CustomTokenAuthenticationFilter">
<constructor-arg name="defaultFilterProcessesUrl" value="/rest/**"/>
<constructor-arg name="authenticationManager" ref="authenticationManager"/>
<constructor-arg name="authenticationSuccessHandler">
<bean class="com.itechart.security.web.security.TokenSimpleUrlAuthenticationSuccessHandler"/>
</constructor-arg>
</bean>
当我向/ rest / login发送用户名和密码时,我在CustomTokenAuthenticationFilter中捕获并且身份验证失败。如何配置我的xml到/ rest / login请求没有过滤和其他/ rest / **带过滤?
这是我的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Security Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherServlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<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>/rest/*</url-pattern>
</filter-mapping>
<resource-ref>
<res-ref-name>jdbc/SecuritySampleDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<welcome-file-list>
<welcome-file>/app/index.html</welcome-file>
</welcome-file-list>
更新1:
public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationFilter.class);
private String excludedUrl;
public CustomTokenAuthenticationFilter(String excludedUrl, String defaultFilterProcessesUrl, AuthenticationManager authenticationManager, AuthenticationSuccessHandler authenticationSuccessHandler) {
super(defaultFilterProcessesUrl);
this.excludedUrl = excludedUrl;
super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
setAuthenticationManager(authenticationManager);
setAuthenticationSuccessHandler(authenticationSuccessHandler);
}
public final String HEADER_SECURITY_TOKEN = "X-CustomToken";
/**
* Attempt to authenticate request - basically just pass over to another method to authenticate request headers
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String token = request.getHeader(HEADER_SECURITY_TOKEN);
logger.info("token found:" + token);
AbstractAuthenticationToken userAuthenticationToken = authUserByToken(token);
if (userAuthenticationToken == null)
throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
return userAuthenticationToken;
}
/**
* authenticate the user based on token
*
* @return
*/
private AbstractAuthenticationToken authUserByToken(String token) {
if (token == null) {
return null;
}
AbstractAuthenticationToken authToken = null;//todo
try {
return authToken;
} catch (Exception e) {
logger.error("Authenticate user by token error: ", e);
}
return authToken;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (((HttpServletRequest) req).getRequestURI().endsWith(excludedUrl)) {
chain.doFilter(req, res);
} else {
super.doFilter(req, res, chain);
}
}
}
这是日志,当我发送请求时:
21:14:00.805 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/rest/test'; against '/rest/**'
21:14:00.808 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 1 of 8 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
21:14:00.818 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 2 of 8 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
21:14:00.826 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 3 of 8 in additional filter chain; firing Filter: 'HeaderWriterFilter'
21:14:00.826 [http-nio-8080-exec-1] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1fd019da
21:14:00.827 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 4 of 8 in additional filter chain; firing Filter: 'CustomTokenAuthenticationFilter'
21:14:00.827 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 5 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
21:14:00.836 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 6 of 8 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
21:14:00.838 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
21:14:00.839 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
21:14:00.839 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
21:14:00.840 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/rest/test'; against '/rest/login'
21:14:00.842 [http-nio-8080-exec-1] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/rest/test'; against '/rest/test'
21:14:00.842 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /rest/test; Attributes: [permitAll]
21:14:00.843 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
21:14:00.862 [http-nio-8080-exec-1] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@66e0e4e6, returned: 1
21:14:00.862 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
21:14:00.862 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
21:14:00.863 [http-nio-8080-exec-1] DEBUG o.s.security.web.FilterChainProxy - /rest/test reached end of additional filter chain; proceeding with original chain
21:14:00.925 [http-nio-8080-exec-1] WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/rest/test] in DispatcherServlet with name 'dispatcherServlet'
21:14:00.933 [http-nio-8080-exec-1] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
21:14:00.933 [http-nio-8080-exec-1] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
答案 0 :(得分:1)
您可以在url
中添加对customTokenAuthenticationFilter
的检查,并在目标为/rest/login
的情况下绕过过滤规则。
考虑这个例子:
@Override
protected final void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException,
IOException {
if (!request.getRequestURL().toString().endsWith("rest/login")) {
... apply filtering logic...
}
filterChain.doFilter(request, response);
}