Spring安全性如何在Servlet上运行

时间:2013-03-01 01:27:19

标签: java spring servlets spring-security

我有一个调用Servlet的java:

public class UserServlet extends HttpServlet {

    @Autowired
    private UserService userService;

    @Override
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        userService.checkUser();
        userService.doSomethingRestricted();
    }

    @Override
    public void init(final ServletConfig config) throws ServletException {
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
            SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
            super.init(config);
    }

}

我的自动服务:

@Component(value = "userService")
public class UserService {

    public boolean checkUser() {
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                if (auth != null && auth.getPrincipal() != null && auth.getPrincipal() instanceof User) {
                    User springUser = (User) auth.getPrincipal();
                    if (springUser != null) {
                        LOG.debug("USER CONNECTED :: {}", springUser.getUsername());
                    }
                }
        } else {
            LOG.debug("NO CONNECTED USER, CREATING ONE");
            Collection<GrantedAuthority> authorities = getGrantedAuthorities();
            org.springframework.security.core.userdetails.User springUser = new org.springframework.security.core.userdetails.User("user","password", true, true, true, true, authorities);
            Authentication auth = new UsernamePasswordAuthenticationToken(springUser, "", authorities);
            SecurityContext sc = new SecurityContextImpl();
            sc.setAuthentication(auth);
            SecurityContextHolder.setContext(sc);
        }
        return true;
    }   


    @Secured({ "CONNECTED" })
    public void doSomethingRestricted() {
        LOG.debug("SOMETHING RESTRICTED HAS BEEN DONE!!");
    }

}
  • 当我第一次测试我的应用程序时,Java客户端向服务器发送POST,服务器将检查用户并且找不到上下文:将创建新的上下文。 / p>

  • 当我随后运行java客户端时,我会找到一个现有的Context(在第一次调用中创建的Context)。

显然缺少某些东西,因为如果第一个用户成功登录,并不意味着任何用户都可以连接。

我错过了什么?起初我想过为每个Java客户端的实例使用会话(我没有Web浏览器客户端所以我需要手动设置会话ID),但是什么时候Spring应该在http请求中获取或设置会话ID?

TL; DR :     SecurityContextHolder.getContext().getAuthentication()在我的例子中做了什么?

2 个答案:

答案 0 :(得分:2)

它为您提供了当前登录用户的身份验证详细信息,是否添加了

<bean id="httpSessionFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

为Web应用程序引入登录,Spring安全性也设计为与POJO一起使用,如果您采用旧方法,则需要在映射中添加此过滤器。如果您在applicationContext中使用http标记,那么它应该按原样运行。

</security:filter-chain-map> 

由于我在应用程序上下文中没有使用新的http标签,因此我使用了Spring安全性。 Spring安全上下文带有不同的过滤器,SecurityContextPersistenceFilter确定上下文的持久化方式。

“org.springframework.security.web.context.SecurityContextPersistenceFilter”用于保持每个会话的安全上下文。

Spring安全性源自与acegi安全性的集成,曾经有过“net.sf.acegisecurity”。 ui.webapp.HttpSessionIntegrationFilter“过滤同一任务

答案 1 :(得分:1)

它是一个过滤器,因此spring可以根据sessionid识别会话。