首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring Security:为什么身份验证是扩展主体?

Spring Security:为什么身份验证是扩展主体?
EN

Stack Overflow用户
提问于 2013-07-19 18:47:55
回答 2查看 4.6K关注 0票数 6

Spring Security假设身份验证是一个主体。

代码语言:javascript
运行
复制
public interface Authentication extends Principal, Serializable {}

HttpServletRequest有getUserPrincipal方法,负责访问主体对象。

让我们考虑一下这个案例:

代码语言:javascript
运行
复制
public interface RealPrincipal extends Principal {
   public Integer getId();
}

公共模块A有真正的主体接口和实现。

模块A使用公共模块A,Servlet Api,不依赖于Spring Security:

模块B使用公共模块A,Servlet Api,并配置Spring Security。此模块负责安全和UserDetails实现。

Web A使用模块A和模块B。

为了使用请求方法,我最终实现了这样一个实现:

代码语言:javascript
运行
复制
public ModelAndView someRequestHandler(Principal principal) {
   User activeUser = (User) ((Authentication) principal).getPrincipal();
   ...
}

这迫使我对模块A和其他模块依赖Spring Security。我认为正确的servlet api抽象不应该依赖于spring安全性。request.getUserPrincipal应返回实数本金。

请解释为什么org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper返回

身份验证而不是Real Principal

编辑:我已经将公共模块A添加到我的场景中,并更新了模块B负责安全性。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-20 00:50:24

正如Luke所说,Spring Security使用主体的身份验证,因为它实现了主体。它不使用Authentication#getPrincipal(),因为不能保证它是一个主体(它是一个对象)。事实上,在大多数情况下,Spring Security的Authentication#getPrincipal()返回一个用户(不实现主体)、一个由框架用户提供的自定义UserDetails或一个字符串。

如果你想让Spring Security来处理这个问题,你可能需要按照Luke的建议使用HttpServletRequestWrapper来实现这个逻辑。例如,您可以执行以下操作:

代码语言:javascript
运行
复制
public RealPrincipalFilter extends OncePerRequestFilter {

    public void doFiter(HttpServletRequest request, HttpServletResponse response, FilterChain) {
        chain.doFilter(new RealPrincipalRequestWrapper(request), response);
    }

    private static final class RealPrincipalRequestWrapper 
          extends HttpServletRequestWrapper {
        public Principal getUserPrincipal() {
            Authentication auth = (Authentication) super.getPrincipal();
            return auth == null ? null : (RealPrincipal) auth.getPrincipal()
        }
    }
}

@Configuration
@EnableWebSecurity
public WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public configure(HttpSecurity http) {
        http
            // ... other config ...
            .addFilterAfter(new RealPrincipalFilter(), SecurityContextHolderAwareRequestFilter.class);
    }
    ...
}

或者,看看我对您的另一个问题的回答,了解与Spring MVC - Injecting Custom Principal to Controllers by Spring Security集成的选项

票数 5
EN

Stack Overflow用户

发布于 2013-07-19 19:04:21

简而言之,Authentication是一个Principal,因此可以在需要API的API(比如您提到的servlet API方法)中使用它。

这在实践中意味着什么?不是很多。Java的Principal接口只有一个方法getName,所以如果您想做的不仅仅是呈现用户名,那么您需要了解更多关于实现的知识。

当您使用“真正的主体”和“适当的servlet api抽象”这两个短语时,您可能应该考虑一下您的意思。例如,如果主体是“真实的”主体,那么如何实现someRequestHandler方法呢?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17744272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档