4

我想在安全认证过程中向 Authentication 对象添加自定义数据:

public class MyAuthFilter extends AbstractAuthenticationProcessingFilter {

    MyUserDetailService userDetailService;  // <==== How to wire??

    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest request,
            HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        ...
        Authentication auth = new UsernamePasswordAuthenticationToken(
               username,
               r.sessionId,
               Arrays.asList(new GrantedAuthority[]{new SimpleGrantedAuthority(grantedUserRole)}));
        auth.setDetails(userDetailService.getDetail()); // <== Save detail to auth.
        return auth;
    }
}

如何连接 MyUserDetailService 服务?

如何将 MyUserDetailService 缓存到主体映射(以避免不必要的调用userDetailService.getDetail()并且不会内存不足)?

PS spring-security.xml

<http use-expressions="true" auto-config="false" entry-point-ref="oauthEntryPoint" authentication-manager-ref="oauthAuthenticationManager">
    <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
    <intercept-url pattern="/login.htm" access="permitAll" />
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <anonymous username="anonymous" enabled="true" granted-authority="AN" key="anonymous-security" />
    <logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutHandler"/>
</http>

<beans:bean id="myFilter" class="com.web.filter.MyAuthFilter"> ...</beans:bean>
4

1 回答 1

3

Spring Security 遵循通常的 Spring 架构,所以我的自定义AbstractAuthenticationProcessingFilter只是普通的 bean。

我不需要将类标记为@Componentspring-security.xml. 我可以使用:

 @Autowired
 private UserService userService;

或者:

public class MyAuthFilter
extends AbstractAuthenticationProcessingFilter
implements ApplicationContextAware {
    private UserService userService;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        userService = applicationContext.getBean(UserService.class);
    }
...
}

将 userDetailService.getDetail() 的值放入身份验证后:

UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
    userName, sessionId,
    AuthorityUtils.createAuthorityList(grantedUserRole));     
auth.setDetails(userService.get(userName));

它将被自动缓存为与身份验证对象的会话保持关联,并且在会话失效后,该关联将传递给 GC。

于 2013-12-04T09:50:28.793 回答