JavaEE学习日志(一百零六): SpringSecurity安全框架入门

SpringSecurity安全框架

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

  • “认证”,是为用户建立一个他所声明的主体。主体一般是指用户,设备或可以在你系 统中执行动作的其他系统。
  • “授权”,指的是一个用户能否在你的应用中执行某个操作,在到达授权判断之前,身份的主题已经由身份验证过程建立了。

安全框架入门

一、引入依赖

<!--引入安全框架web层的内容-->
    <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>
    <!--引入安全框架的标签库-->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
      <version>${spring.security.version}</version>
    </dependency>

二、安全框架配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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/security
       http://www.springframework.org/schema/security/spring-security.xsd
">
    <!--认证-->
    <!--
       配置拦截的规则
       auto-config="使用自带的页面"
       use-expressions="是否使用spel表达式",如果使用表达式:hasRole('ROLE_USER')
   -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置拦截的请求地址,任何请求地址都必须有ROLE_USER的权限 -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>
    </security:http>

    <!-- 配置认证(登录)信息:认证管理器 -->
    <security:authentication-manager>
        <!--认证信息的提供者-->
        <security:authentication-provider>
            <!--用户服务对象-->
            <security:user-service>
                <!--用户信息:临时的账号和密码
                    {noop}:不使用加密
                    authorities:指定用户的认证角色
                -->
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>


</beans>

三、web.xml配置

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--通过全局参数引入配置文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-security.xml</param-value>
  </context-param>
  <!--委派代理过滤器链-->
  <!--配置委派代理过滤器: filter-name必须是:springSecurityFilterChain  -->
  <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>
</web-app>

当访问index.jsp时,就会进入认证页面(默认)

使用自定义页面

添加自定义页面
在这里插入图片描述
配置spring-security.xml

  1. 在原先的基础上,指定安全框架使用的页面,注意login页面请求的路径,只能为login
  2. 对登录、失败和favicon.ico进行放行
  3. 关闭跨站请求伪造
  4. 退出登录的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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/security
       http://www.springframework.org/schema/security/spring-security.xsd
">
    <!--对登录和失败页面放行-->
    <security:http pattern="/login.jsp" security="none"></security:http>
    <security:http pattern="/error.jsp" security="none"></security:http>
    <security:http pattern="/favicon.ico" security="none"></security:http>
    <!--
       配置拦截的规则
       auto-config="使用自带的页面"
       use-expressions="是否使用spel表达式",如果使用表达式:hasRole('ROLE_USER')
   -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置拦截的请求地址,任何请求地址都必须有ROLE_USER的权限 -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>
        <!--指定安全框架使用的页面-->
        <!--
            login-page:指定登录页面
            login-processing-url:登录的请求路径,登录时必须使用该路径
            default-target-url:登录成功后进入的页面
            authentication-failure-url:认证失败要进入的页面
        -->
        <security:form-login login-page="/login.jsp"
                             login-processing-url="/login"
                             default-target-url="/success.jsp"
                             authentication-failure-url="/error.jsp"

        ></security:form-login>
        <!--关闭跨站请求伪造-->
        <security:csrf disabled="true"></security:csrf>
        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
    </security:http>


    <!-- 配置认证(登录)信息:认证管理器 -->
    <security:authentication-manager>
        <!--认证信息的提供者-->
        <security:authentication-provider>
            <!--用户服务对象-->
            <security:user-service>
                <!--用户信息:临时的账号和密码
                    {noop}:不使用加密
                    authorities:指定用户的认证角色
                -->
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>


</beans>

安全框架集成到项目

不指定用户

一、添加spring-security.xml
注意:需要对favicon.ico和静态资源放行

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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/security
       http://www.springframework.org/schema/security/spring-security.xsd
">
    <!--对登录和失败页面放行-->
    <security:http pattern="/login.jsp" security="none"></security:http>
    <security:http pattern="/error.jsp" security="none"></security:http>
    <security:http pattern="/favicon.ico" security="none"></security:http>
    <security:http pattern="/css/**" security="none"></security:http>
    <security:http pattern="/img/**" security="none"></security:http>
    <security:http pattern="/plugins/**" security="none"></security:http>
    <!--
       配置拦截的规则
       auto-config="使用自带的页面"
       use-expressions="是否使用spel表达式",如果使用表达式:hasRole('ROLE_USER')
   -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置拦截的请求地址,任何请求地址都必须有ROLE_USER的权限 -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>
        <!--指定安全框架使用的页面-->
        <!--
            login-page:指定登录页面
            login-processing-url:登录的请求路径,登录时必须使用该路径
            default-target-url:登录成功后进入的页面
            authentication-failure-url:认证失败要进入的页面
        -->
        <security:form-login login-page="/login.jsp"
                             login-processing-url="/login"
                             default-target-url="/index.jsp"
                             authentication-failure-url="/login.jsp"

        ></security:form-login>
        <!--关闭跨站请求伪造-->
        <security:csrf disabled="true"></security:csrf>
        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
    </security:http>


    <!-- 配置认证(登录)信息:认证管理器 -->
    <security:authentication-manager>
        <!--认证信息的提供者-->
        <security:authentication-provider>
            <!--用户服务对象-->
            <security:user-service>
                <!--用户信息:临时的账号和密码
                    {noop}:不使用加密
                    authorities:指定用户的认证角色
                -->
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>


</beans>

二、web.xml
配置委派代理过滤器链,并引入spring-security.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--全局参数,指定配置文件的路径-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:spring/*.xml,classpath:spring-security.xml</param-value>
  </context-param>
  <!--编码过滤器-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <!--委派代理过滤器链-->
  <!--配置委派代理过滤器: filter-name必须是:springSecurityFilterChain  -->
  <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>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!--监听器-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--前端控制器-->
  <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:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

当访问项目的任何一个路径时,就会跳转到login页面
在这里插入图片描述

指定用户

一、在数据库中,添加sys_user表,并添加数据(注意oracle数据库一定要提交!

二、创建实体类SysUser,注意不能创建User,User为安全框架的内置对象

三、创建UserService接口,继承UserDetailsService

/**
 * UserDetailsService:接口中提供了一个方法,loadUserByUsername
 */
public interface UserService extends UserDetailsService {

}

四、实现接口

  1. 重写loadUserByUsername方法,会将页面中输入的username传递过来
  2. 创建UserDao接口,根据username查询用户对象
  3. 当用户不为空时,创建角色集合对象,并添加角色对象(此处为临时角色对象)
  4. 创建UserDetails对象,将usernamepassword角色集合对象三个参数作为构造方法传入(User为实现类)
  5. 返回UserDetails对象
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;
    /**
     * 通过用户名得到用户对象
     * 创建用户详情对象,返回
     * @param username
     * @return UserDetails:用户详情
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名获取用户(SysUser)对象
        SysUser sysUser = userDao.findByUsername(username);
        if(sysUser!=null){
            //创建角色集合对象
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            //创建临时角色对象
            SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER");
            //对象添加到集合中
            authorities.add(grantedAuthority);
            /**
             * 参数1:username
             * 参数2:password
             * 参数3:角色列表对象
             */
            UserDetails user = new User(sysUser.getUsername(),"{noop}"+sysUser.getPassword(),authorities);
            return user;
        }

        return null;

    }
}

五、在配置文件中关联用户服务对象

<!-- 配置认证(登录)信息:认证管理器 -->
    <security:authentication-manager>
        <!--认证信息的提供者:关联用户服务对象,提供账号和密码-->
        <security:authentication-provider user-service-ref="userServiceImpl">
            <!--&lt;!&ndash;用户服务对象&ndash;&gt;
            <security:user-service>
                &lt;!&ndash;用户信息:临时的账号和密码
                    {noop}:不使用加密
                    authorities:指定用户的认证角色
                &ndash;&gt;
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>-->

        </security:authentication-provider>
    </security:authentication-manager>

此时,配置完成,当在login界面中输入数据库中存在的用户时,即可登录成功
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章