【问题标题】:How does spring security work on a ServletSpring Security 如何在 Servlet 上工作
【发布时间】:2013-02-15 10:23:08
【问题描述】:

我有一个调用 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,服务器会检查用户并且找不到上下文:将创建一个新的上下文。

  • 当我随后运行 java 客户端时,我发现了一个现有的上下文(在第一次调用中创建的那个)。

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

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

TL;DRSecurityContextHolder.getContext().getAuthentication() 在我的示例中做了什么?

【问题讨论】:

标签: java spring servlets spring-security


【解决方案1】:

它为您获取当前登录用户的身份验证详细信息,您添加了吗

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

为了引入 web 应用程序的登录,spring security 也被设计为与 POJO 一起使用,如果您使用旧方法,则需要在映射中添加此过滤器。如果您在 applicationContext 中使用 http 标签,那么它应该可以正常工作。

</security:filter-chain-map> 

我已经很久没有在 applicatin Context 中使用没有新的 http 标签的 spring security 了。 spring 安全上下文带有不同的过滤器,SecurityContextPersistenceFilter 决定了上下文是如何被持久化的。

"org.springframework.security.web.context.SecurityContextPersistenceFilter" 用于在每个会话中持久化安全上下文。

Spring 安全性源于它与 acegi 安全性的集成,后者曾经有“net.sf.acegisecurity. ui.webapp.HttpSessionIntegrationFilter" 过滤同一任务

【讨论】:

  • 谢谢你的回答,但我还是不明白。 Java 客户端向服务器发送一个帖子,服务器创建一个上下文。第二个 Java 客户端也向服务器发送一个帖子,Spring 应该如何区分客户端 1(为其创建上下文)和客户端 2(第一次连接)?
  • is for persisting security context per session :什么标识会话? spring 如何告诉客户端 1 的会话与客户端 2 的会话不同。谢谢。
【解决方案2】:

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

【讨论】:

  • 它从哪里获得会话ID?谢谢
  • 从它可以从 HTTP 请求中获取的会话对象。请谷歌更多关于过滤器的信息
猜你喜欢
  • 2015-10-12
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2011-03-09
  • 2015-04-23
  • 2014-11-28
相关资源
最近更新 更多