0
我想部署一個自定義標記過濾器到我的REST應用程序在春天。我可以在我的數據庫中搜索令牌並驗證它是否存在。當我嘗試驗證用戶的權限時,會出現問題:spring安全始終迴應我,即用戶具有角色。權限驗證不起作用後PRE_AUTH_FILTER
這是我的彈簧security.xml文件
<beans:beans ...>
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled" />
<beans:bean id="restServicesEntryPoint" class="org.test.ws.security.RestAuthenticationEntryPoint" />
<beans:bean id="restServicesSuccessHandler" class="org.test.ws.security.RestAuthenticationSuccessHandler" />
<beans:bean id="customAuthenticationProvider" class="org.test.ws.security.CustomAuthenticationProvider" />
<http pattern="/login" security="none" />
<http use-expressions="true" create-session="never" entry-point-ref="restServicesEntryPoint">
<custom-filter ref="restServicesFilter" position="PRE_AUTH_FILTER" />
<intercept-url pattern="/compra" access="ROLE_SUPERVISOR" />
<csrf />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
<beans:bean id="restServicesFilter" class="org.test.ws.security.CustomTokenAuthenticationFilter">
<beans:constructor-arg type="java.lang.String">
<beans:value>/**</beans:value>
</beans:constructor-arg>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="restServicesSuccessHandler" />
</beans:bean>
這是過濾CustomTokenAuthenticationFilter代碼:
package org.test.ws.security;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
// private static final Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationFilter.class);
public final String HEADER_SECURITY_TOKEN = "X-CustomToken";
public CustomTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
setAuthenticationSuccessHandler(new RestAuthenticationSuccessHandler());
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException, IOException,
ServletException {
String token = request.getHeader(HEADER_SECURITY_TOKEN);
AbstractAuthenticationToken userAuthenticationToken = authUserByToken(token);
SecurityContextHolder.getContext().setAuthentication(userAuthenticationToken);
if (userAuthenticationToken == null)
throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
return userAuthenticationToken;
}
@Bean(name = "authenticationManager")
@Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
private AbstractAuthenticationToken authUserByToken(String token) {
if (token == null) {
return null;
}
try {
return new AuthenticationToken(token);
} catch (Exception e) {
// logger.error("Authenticate user by token error: ", e);
}
return null;
}
@Override
public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
if (!request.getMethod().equals("OPTIONS")) {
super.doFilter(request, response, chain);
} else {
chain.doFilter(request, response);
}
}
}
這是CustomAuthenticationProvider代碼:
package org.test.ws.security;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
return authentication;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(AuthenticationToken.class);
}
}
這是AbstractAuthenticationToken代碼:
package org.test.ws.security;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.test.dao.implementaciones.UsuarioDaoImpl;
import org.test.dao.implementaciones.UsuarioRolDaoImpl;
import org.test.dao.modelos.Usuario;
import org.test.dao.modelos.UsuarioRol;
@SuppressWarnings("serial")
public class AuthenticationToken extends AbstractAuthenticationToken {
private ApplicationContext daoContext = new ClassPathXmlApplicationContext("dao-context.xml");
private final Object principal;
private Collection<GrantedAuthority> authorities;
public AuthenticationToken(String token) throws Exception {
super(null);
UsuarioDaoImpl usuarioDao = (UsuarioDaoImpl) daoContext.getBean("UsuarioDaoImpl");
Usuario usuario = usuarioDao.check(token);
super.setAuthenticated(usuario.getActivo());
super.setDetails(usuario);
this.principal = usuario.getUsername();
this.setDetailsAuthorities();
}
@Override
public Object getCredentials() {
return "";
}
@Override
public Object getPrincipal() {
return principal;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}
private void setDetailsAuthorities() {
UsuarioRolDaoImpl usuarioRolDao = (UsuarioRolDaoImpl) daoContext.getBean("UsuarioRolDaoImpl");
authorities = new HashSet<GrantedAuthority>();
List<UsuarioRol> usuariosRol;
try {
usuariosRol = usuarioRolDao.list(0, this.principal.toString());
for (UsuarioRol usuarioRol : usuariosRol) {
authorities.add(new SimpleGrantedAuthority(usuarioRol.getRol()));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
當我運行的代碼,我可以看到這個消息告訴我,比作用在過濾器中創建:
2015-11-03 15:03:13,936 INFO org.springframework.security.config.http.FilterInvocationSecurityMetadataSourceParser - Creating access control expression attribute 'ROLE_ADMIN' for /compra
但總是返回我,即使它沒有用戶被授權具有角色ROLE_ADMIN。
任何關於我在做什麼錯的想法?
在此先感謝!