spring Security用户认证框架

Posted 旺仔的小窝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring Security用户认证框架相关的知识,希望对你有一定的参考价值。

spring security 简介 

spring security 的核心功能主要包括:

认证 (你是谁)
授权 (你能干什么)
攻击防护 (防止伪造身份)
其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。

比如,对于username password认证过滤器来说, 

会检查是否是一个登录请求;

是否包含username 和 password (也就是该过滤器需要的一些认证信息) ;

如果不满足则放行给下一个。

1.创建mavenWeb项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sxw</groupId>
    <artifactId>spring-security</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <url>http://www.example.com</url>
    <properties>
        <jdk.version>1.8</jdk.version>
        <spring.version>4.3.10.RELEASE</spring.version>
        <spring.security.version>4.2.3.RELEASE</spring.security.version>
        <jstl.version>1.2</jstl.version>
        <servlet.version>2.5</servlet.version>
    </properties>

    <dependencies>

        <!-- Spring dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>

        <!-- jstl for jsp page -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- jdk版本插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>

            <!-- tomcat7插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <port>8080</port>
                    <path>/ss1</path>
                    <server>tomcat7</server>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.创建Spring相关配置文件

1)applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <import resource="classpath:spring-security.xml"/>
</beans>

2)springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:contenxt="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描Controller类-->
    <contenxt:component-scan base-package="com.sxw"/>

    <!--注解方式处理器映射器和处理器适配器 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:contenxt="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描Controller类-->
    <contenxt:component-scan base-package="com.sxw"/>

    <!--注解方式处理器映射器和处理器适配器 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

3)spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security-4.2.xsd">
    <!-- <security:http>: spring过滤器链配置:
                 1)需要拦截什么资源
                 2)什么资源什么角色权限
                 3)定义认证方式:HttpBasic,FormLogin(*)
                 4)定义登录页面,定义登录请求地址,定义错误处理方式
             -->
    <security:http>
        <!--
      pattern: 需要拦截资源
      access: 拦截方式
              isFullyAuthenticated(): 该资源需要认证才可以访问
            isAnonymous()  只有匿名用户才可以访问(如果登录用户就无法访问)
              permitAll() :允许所有人( 匿名和登录用户)方法
  -->
        <security:intercept-url pattern="/product/index" access="permitAll()"/>
        <security:intercept-url pattern="/userLogin" access="permitAll()"/>


        <security:intercept-url pattern="/product/add" access="hasRole(\'ROLE_USER\')"/>
        <security:intercept-url pattern="/product/update" access="hasRole(\'ROLE_USER\')"/>


        <security:intercept-url pattern="/product/list" access="hasRole(\'ROLE_ADMIN\')"/>
        <security:intercept-url pattern="/product/delete" access="hasRole(\'ROLE_ADMIN\')"/>


        <security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>

        <!-- security:http-basic: 使用HttpBasic方式进行登录(认证) -->
    <!--<security:http-basic/>-->


        <!--表单形式的验证
        login-page 自定义登录页面
        login-processing-url:登录请求的地址
        authentication-success-handler-ref:登录成功之后的情况
          authentication-failure-handler-ref: 登录失败之后的情况-->
        <security:form-login
                login-page="/userLogin"
                login-processing-url="/securityLogin"
                default-target-url="/product/index"
        authentication-success-handler-ref="myAuthenticationSuccessHandler"
                authentication-failure-handler-ref="myAuthenticationFailureHandler"
        />

    <!--关闭spring security CSRF机制-->
        <security:csrf disabled="true"/>

        <!-- 自定义权限不足处理 -->
        <security:access-denied-handler error-page="/error"/>
    </security:http>


    <security:authentication-manager>
        <!-- security:authentication-manager: 认证管理器
                1)认证信息提供方式(账户名,密码,当前用户权限)
                -->

<!--        <security:authentication-provider>
        <security:user-service>
                 <security:user name="eric" password="123456" authorities="ROLE_USER"/>
                <security:user name="jack" password="123456" authorities="ROLE_ADMIN"/>
            </security:user-service>
        </security:authentication-provider>-->




        <!--定义USerDetailServer方式-->
        <security:authentication-provider user-service-ref="myUserDemoServer"/>

    </security:authentication-manager>

    <bean id="myUserDemoServer" class="com.sxw.security.MyUserDemoServer"/>
    <bean id="myAuthenticationSuccessHandler" class="com.sxw.security.MyAuthenticationSuccessHandler"/>
    <bean id="myAuthenticationFailureHandler" class="com.sxw.security.MyAuthenticationFailureHandler"/>
</beans>

3.编写web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- SpringSecurity过滤器链  -->
    <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>


    <!-- 启动Spring  -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml
        </param-value>
    </context-param>

    <!--启动SpringMVC-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 服务器启动加载Servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3.编写拦截器

1)登录成功处理

/**
 * @description: 登录成功处理
 * @author: 
 * @createDate: 2020/4/4
 * @version: 1.0
 */
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {



   /*json框架的工具类*/
    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     *
     * @description:TODO
     * @params:3. 认证成功后的信息    * @return:
     * @author: 
     * @time: 2020/4/4 12:26
     */

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        //返回json字符串
        Map<String,Object> result = new HashMap();
        result.put("success",true);
        String json =objectMapper.writeValueAsString(result);
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(json);

    }
}

2)登录失败的逻辑

/**
 * @description: 登录失败的逻辑
 * @author: 
 * @createDate: 2020/4/4
 * @version: 1.0
 */
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {



    /*json框架的工具类*/
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        //返回json字符串
        Map<String,Object> result = new HashMap();
        result.put("Failure",false);
        String json =objectMapper.writeValueAsString(result);
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(json);
    }
}

3)用户权限的管理

/**
 * @description: 用户权限的管理
 * @author: 
 * @createDate: 2020/4/4
 * @version: 1.0
 */

public class MyUserDemoServer implements UserDetailsService {

    /**
     *
     * @description:读取数据库的信息
     * @params:
     * @return:
     * @author: 
     * @time: 2020/4/4 12:00
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //UserDetails: 封装用户数据的接口
        User user = new User("eric","123456",
                AuthorityUtils.
                        commaSeparatedStringToAuthorityList("ROLE_USER"));

        return user;
    }
}

2.SpringBoot整合

1)添加依赖