登录/注销在REST和Spring 3(Login/logout in REST with Spri

2019-07-19 09:45发布

我们正在开发的RESTful web服务使用Spring 3,我们需要有登录/注销,类似的功能/webservices/login/<username>/<password>//webservices/logout 。 会议应存放在上下文,直到会话超时或退出,以允许其他web服务的消费。 访问Web服务的任何请求,而不会话信息,应予以拒绝。 寻找国家的最先进的解决方案,此方案。

其实我复活的问题在这里提出的Spring Security 3编程方式登录 ,仍然无法正常回答。 请说明在web.xml中同样也需要改变。

Answer 1:

我建议完全手动定义你的春季安全过滤器。 这并不难,你克服你的登录/注销行为的完全控制。

首先,你需要标准的web.xml Blurb的委托过滤器链处理,以春季(如果你不是对Servlet API的版本3中删除异步支持):

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <async-supported>true</async-supported>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>



<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

现在,在安全环境下,你将分别定义过滤器为每个路径。 过滤器可以验证用户,注销用户,查看安全证书等。

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <sec:filter-chain-map path-type="ant">
        <sec:filter-chain pattern="/login" filters="sif,wsFilter"/>
        <sec:filter-chain pattern="/logout" filters="sif,logoutFilter" />
        <sec:filter-chain pattern="/rest/**" filters="sif,fsi"/>
    </sec:filter-chain-map>
</bean>

上面的XML告诉Spring通过过滤器链,以请求传递给特定上下文相关的网址。 在任何过滤器链的第一件事就是建立安全上下文 - “SIF”豆需要的照顾。

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

基于所述安全上下文:(登录/注销用户读取),或做出决定是否允许访问链中下一个过滤器现在可以将数据添加到安全上下文。

为了您的登录网址,你会希望有一个过滤器,从请求读取验证数据,验证它,并依次将其存储在安全的情况下(这是存储在会话):

<bean id="wsFilter" class="my.own.security.AuthenticationFilter">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="authenticationSuccessHandler" ref="myAuthSuccessHandler"/>
  <property name="passwordParameter" value="pass"></property>
  <property name="usernameParameter" value="user"></property>
  <property name="postOnly" value="false"></property>

你可以使用Spring通用UsernamePasswordAuthenticationFilter但我用我自己的实现的原因是为了继续过滤器链处理(默认实现假定用户会被重定向成功的权威性和终止过滤器链),并能够处理验证每次用户名和密码传递它:

public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
    return ( StringUtils.hasText(obtainUsername(request)) && StringUtils.hasText(obtainPassword(request)) );
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
        Authentication authResult) throws IOException, ServletException{
    super.successfulAuthentication(request, response, chain, authResult);
    chain.doFilter(request, response);
}

您可以添加使用HTTP基本身份验证标头任意数量的自己的过滤器实现/登录路径,如身份验证,摘要头部,甚至提取请求主体的用户名/密码。 Spring提供了一堆的过滤器这一点。

我有我自己的身份验证成功处理谁覆盖默认重定向策略:

public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

   @PostConstruct
   public void afterPropertiesSet() {
       setRedirectStrategy(new NoRedirectStrategy());
   }

    protected class NoRedirectStrategy implements RedirectStrategy {

        @Override
        public void sendRedirect(HttpServletRequest request,
                HttpServletResponse response, String url) throws IOException {
            // no redirect

        }

    }

}

你不必有定制的权威性成功处理程序(也可能是定制的身份验证过滤器为好),如果你确定与用户成功登录后,被重定向(重定向URL可定制,检查文档)

定义谁是负责检索用户的详细信息认证管理器:

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="myAuthAuthProvider"/>
</sec:authentication-manager>

 <bean id="myAuthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService">
        <bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <property name="userDetailsService" ref="myUserDetailsImpl"/>
        </bean>
    </property>
</bean>

你将不得不在这里提供自己的用户资料bean实现。

注销过滤器:负责清除安全上下文

<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
</bean>

通用认证的东西:

<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="allowIfAllAbstainDecisions" value="false"/>
    <property name="decisionVoters">
        <list>
            <ref bean="roleVoter"/>
        </list>
    </property>
</bean>

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>

<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>

访问控制滤波器(应该是不言自明的):

<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="myAuthenticationManager"/>
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
    <property name="securityMetadataSource">
        <sec:filter-invocation-definition-source>
            <sec:intercept-url pattern="/rest/**" access="ROLE_REST"/>
        </sec:filter-invocation-definition-source>
    </property>
</bean>

你也应该能够与保护您的REST服务@Secured上的方法的注释。

遗憾的任何可能的输入 - 语境以上是从现有的REST服务的webapp弹拨。

也可以至少做大部分的是什么用股票在这里实现sec Spring标签,但是我更喜欢自定义的方法,因为这给了我最大程度的控制。

希望这至少可以让你开始。



文章来源: Login/logout in REST with Spring 3