Spring Security(四)

简介: Spring Security(四)

⑦. 退出登录


7. 退出登录


  • ①. 用户完成登录后Spring Security框架会记录当前用户认证状态为已认证状态,即表示用 户登录成功了。那用户如何退出登录呢?我们可以在spring-security.xml文件中进行如下 配置:

微信图片_20220105214108.png

   <!--
           logout:退出登录
           logout-url:退出登录操作对应的请求路径
           logout-success-url:退出登录后的跳转页面
           默认退出的url是/logout
           注意:要求是post的提交方式提交
         -->
   <security:logout logout-url="/logout.do"
                    logout-success-url="/login.html" invalidate-session="true"/>


  • ②. 通过上面的配置可以发现,如果用户要退出登录,只需要请求/logout.do这个URL地址就 可以,同时会将当前session失效,最后页面会跳转到login.html页面


  • ③.注意:默认退出的url是/logout | 要求是post的提交方式提交


⑧. 页面iframe设置为可访问[同源策略]


8. iframe设置为可访问 [ 官方称为:同源策略 ]


<security:http auto-config="true" use-expressions="true">
  <security:headers>
      <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
      <security:frame-options policy="SAMEORIGIN"></security:frame-options>
  </security:headers>
</security:http>


微信图片_20220105214316.png


⑨. 登录成功获取用户姓名


  • SecurityContextHolder.getContext().getAuthentication( ).getPrincipal( );


    //获取当前用户登录的用户名
    @RequestMapping("/getUsername")
    public Result getUsername(){
        //spring security认证通过后,会将用户名存到框架的上下文对象中
        //底层基于HttpSession
        try{
            User user =
                    (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
          return new Result(true, MessageConstant.GET_USERNAME_SUCCESS, user.getUsername());
        }catch (Exception e){
            e.getStackTrace();
            return new Result(false,MessageConstant.GET_USERNAME_FAIL);
        }
    }


微信图片_20220105214353.png


⑩. 登录日志的处理流程


10>. 登录成功处理器


  • ①. spring security为我们提供了一个叫“登录成功处理器”的组件,我们可以实现在登录后进行的后续处理逻辑


//测试
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        System.out.println(".........WO LAI LE");
        request.getRequestDispatcher("/main.html").forward(request,response);
    }
}


②. applicationContext_security.xml新增配置


 <bean id="loginHandler" class="com.qingcheng.controller.AuthenticationSuccessHandlerImpl"></bean>
  <security:form-login
            login-page="/login.html"
            username-parameter="username"
            password-parameter="password"
            login-processing-url="/login.do"
            default-target-url="/main.html"
            authentication-failure-url="/login.html"
            authentication-success-handler-ref="loginHandler"
        ></security:form-login>


微信图片_20220105214429.png


⑩. 实战演示


  • ①. 需求:根据不同的用户授予不同的角色和权限


image.png


②. 导包


<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring‐security‐web</artifactId> 
    <version>5.0.5.RELEASE</version> 
  </dependency> 
  <dependency> 
    <groupId>org.springframework.security</groupId>
    <artifactId>spring‐security‐config</artifactId> 
    <version>5.0.5.RELEASE</version> 
  </dependency>


③. web.xml


  <filter>
    <!--
      DelegatingFilterProxy用于整合第三方框架
      整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
    否则会抛出NoSuchBeanDefinitionException异常
    -->
    <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-security[记得在spring-mvc.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:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:security="http://www.springframework.org/schema/security"
       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://code.alibabatech.com/schema/dubbo
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
                     http://www.springframework.org/schema/security
                     http://www.springframework.org/schema/security/spring-security.xsd">
    <!--配置哪些资源匿名可以访问(不登录也可以访问)-->
    <!--<security:http security="none" pattern="/pages/a.html"></security:http>
    <security:http security="none" pattern="/pages/b.html"></security:http>-->
    <!--<security:http security="none" pattern="/pages/**"></security:http>-->
    <security:http security="none" pattern="/login.html"></security:http>
    <security:http security="none" pattern="/css/**"></security:http>
    <security:http security="none" pattern="/img/**"></security:http>
    <security:http security="none" pattern="/js/**"></security:http>
    <security:http security="none" pattern="/plugins/**"></security:http>
    <!--
        auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面
        use-expressions:是否使用spring security提供的表达式来描述权限
    -->
    <security:http auto-config="true" use-expressions="true">
        <security:headers>
            <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
            <security:frame-options policy="SAMEORIGIN"></security:frame-options>
        </security:headers>
        <!--配置拦截规则,/** 表示拦截所有请求-->
        <!--
            pattern:描述拦截规则
            asscess:指定所需的访问角色或者访问权限
        -->
        <!--只要认证通过就可以访问-->
        <security:intercept-url pattern="/pages/**"  access="isAuthenticated()" />
        <!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表单.页面提交的登录表单请求是由框架负责处理-->
        <!--
            login-page:指定登录页面访问URL
        -->
        <security:form-login
                login-page="/login.html"
                username-parameter="username"
                password-parameter="password"
                login-processing-url="/login.do"
                default-target-url="/pages/main.html"
                authentication-failure-url="/login.html"></security:form-login>
        <!--
          csrf:对应CsrfFilter过滤器
          disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403)
        -->
        <security:csrf disabled="true"></security:csrf>
        <!--
          logout:退出登录
          logout-url:退出登录操作对应的请求路径
          logout-success-url:退出登录后的跳转页面
        -->
        <security:logout logout-url="/logout.do"
                         logout-success-url="/login.html" invalidate-session="true"/>
    </security:http>
    <!--配置认证管理器-->
    <security:authentication-manager>
        <!--配置认证提供者-->
        <security:authentication-provider user-service-ref="springSecurityUserService">
            <!--
                    配置一个具体的用户,后期需要从数据库查询用户
            <security:user-service>
                <security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/>
            </security:user-service>
            -->
            <!--指定度密码进行加密的对象-->
            <security:password-encoder ref="passwordEncoder"></security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>
    <!--配置密码加密对象-->
    <bean id="passwordEncoder"
          class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
    <!--开启注解方式权限控制-->
    <security:global-method-security pre-post-annotations="enabled" />
</beans>


④. UserService [ 重点掌握 ]


@Component
public class SpringSecurityUserService implements UserDetailsService {
    //使用dubbo通过网络远程调用服务提供方获取数据库中的用户信息
    @Reference
    private UserService userService;
    //根据用户名查询数据库获取用户信息
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername2(username);
        if(user == null){
            //用户名不存在
            return null;
        }
        List<GrantedAuthority> list = new ArrayList<>();
        //动态为当前用户授权
        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            //遍历角色集合,为用户授予角色
            list.add(new SimpleGrantedAuthority(role.getKeyword()));
            Set<Permission> permissions = role.getPermissions();
            for (Permission permission : permissions) {
                //遍历权限集合,为用户授权
                list.add(new SimpleGrantedAuthority(permission.getKeyword()));
            }
        }
        org.springframework.security.core.userdetails.User securityUser = new org.springframework.security.core.userdetails.User(username,user.getPassword(),list);
        return securityUser;
    }
}


⑤. mybatis 的sql编写 [ 重点掌握 ]


User:
    private Integer id; // 主键
    private Date birthday; // 生日
    private String gender; // 性别
    private String username; // 用户名,唯一
    private String password; // 密码
    private String remark; // 备注
    private String station; // 状态
    private String telephone; // 联系电话
    private Set<Role> roles = new HashSet<Role>(0);//对应角色集合
    userDao.xml
    <resultMap id="baseMap" type="com.itheima.pojo.User">
        <id column="id" property="id"></id>
        <result column="birthday" property="birthday"></result>
        <result column="gender" property="gender"></result>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="remark" property="remark"></result>
        <result column="station" property="station"></result>
        <result column="telephone" property="telephone"></result>
    </resultMap>
    <resultMap id="UserMap" type="com.itheima.pojo.User" extends="baseMap">
       <!-- private Set<Role> roles = new HashSet<Role>(0);//对应角色集合-->
       <collection
               property="roles"
               ofType="com.itheima.pojo.Role"
               这里的id是select * from t_user...查询出来的结果的id
               column="id"         
               select="com.itheima.dao.RoleDao.findUserIdByRoles">
       </collection>
    </resultMap>
    <select id="findByUsername2" parameterType="string" resultMap="UserMap">
        select * from t_user where username=#{username}
    </select>


public class Role implements Serializable {
    private Integer id;
    private String name; // 角色名称
    private String keyword; // 角色关键字,用于权限控制
    private String description; // 描述
    private Set<User> users = new HashSet<User>(0);
    private Set<Permission> permissions = new HashSet<Permission>(0);
    }
RoleDao.xml
    <resultMap id="baseMap" type="com.itheima.pojo.Role">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="keyword" property="keyword"></result>
        <result column="description" property="description"></result>
    </resultMap>
    <resultMap id="RolesMap" type="com.itheima.pojo.Role" extends="baseMap">
        <collection property="permissions"
                    column="id"
                    ofType="com.itheima.pojo.Permission"
                    select="com.itheima.dao.PermissionDao.findRoleIdsByPserssion">
        </collection>
    <select id="findUserIdByRoles" resultMap="RolesMap" parameterType="int">
        select * from t_role where id in(select role_id from t_user_role
         where user_id=#{user_id})
    </select>
perssionDao.xml
    <select id="findRoleIdsByPserssion" resultType="com.itheima.pojo.Permission" 
    parameterType="int">
    select * from t_permission where id in(select permission_id
     from t_role_permission where role_id=#{role_id})
    </select>


相关文章
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据库
实现基于Spring Security的权限管理系统
实现基于Spring Security的权限管理系统
|
5月前
|
安全 Java 数据安全/隐私保护
解析Spring Security中的权限控制策略
解析Spring Security中的权限控制策略
|
6月前
|
JSON 安全 Java
Spring Security 6.x 微信公众平台OAuth2授权实战
上一篇介绍了OAuth2协议的基本原理,以及Spring Security框架中自带的OAuth2客户端GitHub的实现细节,本篇以微信公众号网页授权登录为目的,介绍如何在原框架基础上定制开发OAuth2客户端。
225 4
Spring Security 6.x 微信公众平台OAuth2授权实战
|
6月前
|
存储 安全 Java
Spring Security 6.x OAuth2登录认证源码分析
上一篇介绍了Spring Security框架中身份认证的架构设计,本篇就OAuth2客户端登录认证的实现源码做一些分析。
256 2
Spring Security 6.x OAuth2登录认证源码分析
|
6月前
|
安全 Java 数据安全/隐私保护
Spring Security 6.x 一文快速搞懂配置原理
本文主要对整个Spring Security配置过程做一定的剖析,希望可以对学习Spring Sercurity框架的同学所有帮助。
302 5
Spring Security 6.x 一文快速搞懂配置原理
|
6月前
|
安全 Java API
Spring Security 6.x 图解身份认证的架构设计
【6月更文挑战第1天】本文主要介绍了Spring Security在身份认证方面的架构设计,以及主要业务流程,及核心代码的实现
93 1
Spring Security 6.x 图解身份认证的架构设计
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据安全/隐私保护
使用Java和Spring Security实现身份验证与授权
使用Java和Spring Security实现身份验证与授权
|
5月前
|
存储 安全 Java
Spring Security在企业级应用中的应用
Spring Security在企业级应用中的应用