Spring Security 4 - REST和安全性问题

时间:2016-10-11 02:31:09

标签: java spring rest spring-mvc spring-security

最近我一直在尝试将Spring Security集成到我的REST API中。我发现以下SO回答Login/logout in REST with Spring 3并尝试在我的项目中实现它。

在修补了一些小事后,我似乎遇到了一些问题。

  1. 在我的intercept-url即使我设置了对permitAll的访问权限,我也会收到以下错误:

      

    HTTP状态500 - 在SecurityContext中找不到Authentication对象

  2. 当我访问localhost:8080/Login尝试登录时,没有弹出窗口,我收到404
  3. 这是我的代码:

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        version="3.1">
        <display-name>name</display-name>
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
            classpath:applicationContext.xml,
            classpath:spring-security.xml
        </param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <filter>
            <filter-name>springSecurityFilterChain</filter-name>
            <filter-class>
                org.springframework.web.filter.DelegatingFilterProxy
            </filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <servlet>
            <servlet-name>jersey-serlvet</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>com.trackmygymlife.webservices</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>jersey-serlvet</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    spring-security.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        classpath:org/springframework/beans/factory/xml/spring-beans-4.1.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-4.0.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-4.1.xsd">
    
    
        <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
            <constructor-arg>
                <list>
                    <sec:filter-chain pattern="/login" filters="sif,wsFilter" />
                    <sec:filter-chain pattern="/logout" filters="sif,logoutFilter" />
                    <sec:filter-chain pattern="/rest/**" filters="sif,fsi" />
                </list>
            </constructor-arg>
        </bean>
    
        <bean id="sif"
            class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
    
        <bean id="wsFilter" class="com.trackmygymlife.security.UserAuthenticationFilter">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="authenticationSuccessHandler" ref="authSuccessHandler" />
            <property name="passwordParameter" value="pass"></property>
            <property name="usernameParameter" value="user"></property>
            <property name="postOnly" value="false"></property>
        </bean>
    
        <bean id="authSuccessHandler"
            class="com.trackmygymlife.security.AuthenticationSuccessHandler"></bean>
    
        <sec:authentication-manager alias="authenticationManager">
            <sec:authentication-provider user-service-ref="userService" >
                <sec:password-encoder hash="bcrypt"></sec:password-encoder>
            </sec:authentication-provider>
        </sec:authentication-manager>
    
        <bean id="authenticationProvider"
            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="userService" />
                </bean>
            </property>
        </bean>
    
        <bean id="userService"
            class="com.trackmygymlife.serviceimpl.TrackMyGymLifeUserService" />
    
        <bean id="logoutFilter"
            class="org.springframework.security.web.authentication.logout.LogoutFilter">
            <constructor-arg index="0" value="/">
            </constructor-arg>
            <constructor-arg index="1">
                <bean
                    class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
            </constructor-arg>
        </bean>
    
        <bean id="httpRequestAccessDecisionManager"
            class="org.springframework.security.access.vote.AffirmativeBased">
            <property name="allowIfAllAbstainDecisions" value="false" />
            <constructor-arg>
                <list>
                    <ref bean="roleVoter" />
                    <bean class="org.springframework.security.access.vote.RoleVoter "/>
                </list>
            </constructor-arg>
            <!-- <property name="decisionVoters"> -->
            <!-- <list> -->
            <!-- </list> -->
            <!-- </property> -->
        </bean>
    
        <bean id="roleVoter"
            class="org.springframework.security.web.access.expression.WebExpressionVoter" />
    
        <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="authenticationManager" />
            <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
            <property name="securityMetadataSource">
                <sec:filter-security-metadata-source>
                    <sec:intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')" />
                </sec:filter-security-metadata-source>
            </property>
        </bean>
    
    </beans>
    

    AuthenticationSuccessHandler

    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 {            
            }
        }
    

    UserAuthenticationFilter

    public class UserAuthenticationFilter 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);
        }
    }
    

    任何帮助都将不胜感激。

0 个答案:

没有答案