Spring5-securty具体实现

0. 加入maven依赖

1. 放行首页登录页面和静态资源

@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
     * 用户授权相关()
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests() // 对请求进行授权 先授权再指定其他请求 否则授权无效
                .antMatchers("/**/*.css*", "/**/*.js", "/**/*.png", "/**/*.jpg",
                "/**/*.jpeg", "/**/*.gif", "/**/*.ico", "/**/fonts/*","/toLogin") // 授权路径
                .permitAll() // 无条件访问
           ;
    }
}     

2. 指定登陆信息
在这里插入图片描述

@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
     * 用户授权相关()
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests() // 对请求进行授权 先授权再指定其他请求 否则授权无效
                .antMatchers("/**/*.css*", "/**/*.js", "/**/*.png", "/**/*.jpg",
                "/**/*.jpeg", "/**/*.gif", "/**/*.ico", "/**/fonts/*","/toLogin") // 授权路径
                .permitAll() // 无条件访问
                .and()
                .authorizeRequests()
                .anyRequest() // 其他请求
                .authenticated() // 必须经过授权认证
                .and()
                .formLogin()
                .loginPage("/toLogin") // 登录页面
                .loginProcessingUrl("/login") // 登录操作地址
                .usernameParameter("loginAcct") // 指定登录用户名 name
                .passwordParameter("password") // 指定密码 name
                .defaultSuccessUrl("/static/admin-main.jsp") // 指定默认登陆成功去的页面
                .and().csrf().disable()
        ;
    }
}     

3. 内存方式访问

/**
     * 用户登录相关
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(getMyUserDetailsService());

        // 内存中指定用户名 密码 进行验证
        auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance())
                .withUser("admin").password("admin").roles("ADMIN")
        .and().withUser("gm").password("gm").roles("ADD","EDIT");
    }

4. 数据库方式用户名密码

/**
     * 用户登录相关
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 真实环境 数据库方式登陆 用户名验证 登陆封装角色权限信息 都在 userDetailsService
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);

//        // 内存中指定用户名 密码 进行验证
//        auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance())
//                .withUser("admin").password("admin").roles("ADMIN")
//        .and().withUser("gm").password("gm").roles("ADD","EDIT");
    }

5. 实现MyUserDetailsService

package com.gq.mmc.service;


import com.gq.mmc.entity.Admin;
import com.gq.mmc.entity.Role;
import com.gq.mmc.entity.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    IAdminService adminService;
    @Autowired
    IRoleService roleService;
    @Autowired
    IAuthService authService;

    /**
     * 数据库方式检查用户 在此之后完成密码校验
     * @param loginAcct
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String loginAcct) throws UsernameNotFoundException {
        // 查询出用户信息
        Admin user = adminService.getAdminByUsername(loginAcct);
        int userId = user.getId();
        // 根据userId 查询已分配的角色信息
        List<Role> roles = roleService.getAssignedRolesByAdminId(userId);
        // 根据userId 查询权限
        List<String> auths = authService.getAssignedAuthsByAdminId(userId);
        // 封装角色
        List<GrantedAuthority> authList = new ArrayList<>();
        for (Role role: roles) {
            String roleName = "ROLE_" + role.getRoleName();
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(roleName);
            authList.add(simpleGrantedAuthority);
        }
        // 封装权限
        for (String authName: auths) {
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authName);
            authList.add(simpleGrantedAuthority);
        }
        // 封装security User对象 由于需要系统用户 其他信息 所以此处使用 扩展了以后的Security User对象
        User securtyUser = new SecurityUser(user, authList);
        return securtyUser;
    }
}

6. 自定义SecurityUser对象集成User对象 封装系统用户对象在其中

package com.gq.mmc.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.util.Collection;

/**
 *  由于security User对象只有 username password 信息
 *  想要获取系统用户的其他信息 需要以 SecurityUser对 security User对象进行扩展
 */
public class SecurityUser extends User  {

    // 此处即是 系统 用户名信息
    private Admin user;

    public SecurityUser(Admin secuser, Collection<? extends GrantedAuthority> authorities) {
        // 调用父类构造器 将系统用户的 用户名 密码 传入security User对象 以便下一步进行用户名密码校验
        super(secuser.getUserName(), secuser.getUserPswd(), authorities);
        // 登陆后将密码置空 防止页面获取密码信息 符合 Spring security 原始置空规则
        secuser.setUserPswd(null);
        this.user = user;
    }

    public Admin getUser() {
        return user;
    }

    public void setUser(Admin user) {
        this.user = user;
    }
}

7. 页面显示用户信息

<!--先添加 Spring security 的权限标签库-->
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
<!--然后在页面 可以根据 标签获取用户信息 注 principal对象里面封装的就是用户对象-->
<security:authentication property="principal.user.userName">

8. 控制角色访问方法的方式
8.1 config控制
在这里插入图片描述
8.2 注解控制
在这里插入图片描述
在这里插入图片描述
9. 页面元素控制
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/q18729096963/article/details/105545352