zoukankan      html  css  js  c++  java
  • springboot 整合 springsecurity

    导入jar包

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>

    springsecurity的配置类(依赖于方法上加注解 进行权限验证)第一种 方法

    @PreAuthorize("hasAuthority('/user/del')")
    package com.liuchao.securitydemo.security.config;
    
    import com.liuchao.securitydemo.security.config.CustomUserDetailsService;
    import com.liuchao.securitydemo.security.entity.Menu;
    import com.liuchao.securitydemo.security.mapper.UserMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.BeanIds;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Component
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true) //开启方法权限控制  @PreAuthorize("hasAuthority('/user/del')")在方法上加上这个可以验证权限
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Resource
        private UserMapper userMapper;
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws  Exception{
            auth.userDetailsService(customUserDetailsService())//配置用户验证登录的类
                    .passwordEncoder(passwordEncoder());//这个是密码校验的类
        }
    
      //配置校验的路径和不校验的路径
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    // 所有用户均可访问的资源
                    .antMatchers( "/favicon.ico","/css/**","/common/**","/js/**","/images/**","/captcha.jpg","/login","/userLogin","/login-error").permitAll()
                    // 任何尚未匹配的URL只需要验证用户即可访问
                    .anyRequest().authenticated()
                    .and()
                    .formLogin().loginPage("/login").successForwardUrl("/index").failureForwardUrl("/login?error=1")
                    .and()
                    //权限拒绝的页面
                    .exceptionHandling().accessDeniedPage("/403");
    
            http.logout().logoutSuccessUrl("/login");
       /*     List<Menu> allMenu = userMapper.findAllMenu();
            ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests();
            for(Menu menu:allMenu){
                expressionInterceptUrlRegistry.antMatchers(menu.getUrl()).hasAnyAuthority(menu.getUrl());
            }
            expressionInterceptUrlRegistry.antMatchers( "/favicon.ico","/css/**","/common/**","/js/**","/images/**","/captcha.jpg","/login","/userLogin","/login-error").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().loginPage("/login").successForwardUrl("/index").failureForwardUrl("/login?error=1")
                    .and()
                    .exceptionHandling().accessDeniedPage("/403");*/
        }
    
       /**
         * 设置用户密码的加密方式
         * @return
         */
        @Bean
        public Md5PasswordEncoder passwordEncoder() {//密码校验器并注入spring
            return new Md5PasswordEncoder();
    
        }
    
        /**
         * 自定义UserDetailsService,授权
         * @return
         */
        @Bean
        public CustomUserDetailsService customUserDetailsService(){//校验用户登录的类交注入spring
            return new CustomUserDetailsService();
        }
    
    
        @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
    
    
    }

    springsecurity的配置类(依赖于配置进行权限验证)第二种方法(可以不用依赖于方法上的注解 来进行权限验证)

    package com.liuchao.securitydemo.security.config;
    
    import com.liuchao.securitydemo.security.config.CustomUserDetailsService;
    import com.liuchao.securitydemo.security.entity.Menu;
    import com.liuchao.securitydemo.security.mapper.UserMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.BeanIds;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Component
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true) //开启方法权限控制  @PreAuthorize("hasAuthority('/user/del')")在方法上加上这个可以验证权限
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Resource
        private UserMapper userMapper;
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws  Exception{
            auth.userDetailsService(customUserDetailsService())
                    .passwordEncoder(passwordEncoder());
        }
    
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
           /* http.authorizeRequests()
                    // 所有用户均可访问的资源
                    .antMatchers( "/favicon.ico","/css/**","/common/**","/js/**","/images/**","/captcha.jpg","/login","/userLogin","/login-error").permitAll()
                    // 任何尚未匹配的URL只需要验证用户即可访问
                    .anyRequest().authenticated()
                    .and()
                    .formLogin().loginPage("/login").successForwardUrl("/index").failureForwardUrl("/login?error=1")
                    .and()
                    //权限拒绝的页面
                    .exceptionHandling().accessDeniedPage("/403");
    
            http.logout().logoutSuccessUrl("/login");*/
           List<Menu> allMenu = userMapper.findAllMenu();
            ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests();
            for(Menu menu:allMenu){
                expressionInterceptUrlRegistry.antMatchers(menu.getUrl()).hasAnyAuthority(menu.getUrl());//给每个地址进行授权只有有这个权限的才能访问
            }
            expressionInterceptUrlRegistry.antMatchers( "/favicon.ico","/css/**","/common/**","/js/**","/images/**","/captcha.jpg","/login","/userLogin","/login-error").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().loginPage("/login").successForwardUrl("/index").failureForwardUrl("/login?error=1")
                    .and()
                    .exceptionHandling().accessDeniedPage("/403");
            http.logout().logoutSuccessUrl("/login");
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            super.configure(auth);
        }
    
        /**
         * 设置用户密码的加密方式
         * @return
         */
        @Bean
        public Md5PasswordEncoder passwordEncoder() {
            return new Md5PasswordEncoder();
    
        }
    
        /**
         * 自定义UserDetailsService,授权
         * @return
         */
        @Bean
        public CustomUserDetailsService customUserDetailsService(){
            return new CustomUserDetailsService();
        }
    
    
        @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
    
    
    }

    验证用户登录的类

    package com.liuchao.securitydemo.security.config;
    
    import com.liuchao.securitydemo.security.entity.Menu;
    import com.liuchao.securitydemo.security.entity.User;
    import com.liuchao.securitydemo.security.mapper.UserMapper;
    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.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import javax.annotation.Resource;
    import java.util.ArrayList;
    import java.util.List;
    
    //@Component
    public class CustomUserDetailsService implements UserDetailsService {
    
        @Resource
        private UserMapper userMapper;
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
            User user = userMapper.findByName(s);
            if(StringUtils.isEmpty(user)){
                throw new UsernameNotFoundException("账号不存在");
            }
    
            List<Menu> menuList = userMapper.findByUserId(user.getId());
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
                for(Menu menu: menuList){
                    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(menu.getUrl());
                    //此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
                    grantedAuthorities.add(grantedAuthority);
    
               }
            user.setAuthorities(grantedAuthorities);//给用户授权
    
            return user;
        }
    }

    用户的实体类必需要实现一个UserDetails类

    package com.liuchao.securitydemo.security.entity;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.io.Serializable;
    import java.util.Collection;
    import java.util.Date;
    import java.util.List;
    
    public class User  implements UserDetails,Serializable {
        private static final long serialVersionUID = -962358173215433342L;
        private Integer id;
        private String username;
        private String nickname;
        private String admin;
        private Date createDate;
        private String password;
    
        private List<? extends GrantedAuthority> authorities;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getNickname() {
            return nickname;
        }
    
        public void setNickname(String nickname) {
            this.nickname = nickname;
        }
    
        public String getAdmin() {
            return admin;
        }
    
        public void setAdmin(String admin) {
            this.admin = admin;
        }
    
        public Date getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public void setAuthorities(List<? extends GrantedAuthority> authorities) {
            this.authorities = authorities;
        }
    
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }
    
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public String getUsername() {
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    }

    密码校验器

    package com.liuchao.securitydemo.security.config;
    
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    /**
     * 自定义密码比较器 3
     * 在此 密码我就不加密了
     */
    public class Md5PasswordEncoder implements PasswordEncoder {
        @Override
        public String encode(CharSequence charSequence) {
            return charSequence.toString();
        }
    
    
        @Override
        public boolean matches(CharSequence charSequence, String s) {
    
            return s.equals(charSequence);
        }
    }

    springSecurity的获取用户 判断权限的一个工具类

    package com.liuchao.securitydemo.security.util;
    
    import com.liuchao.securitydemo.security.entity.User;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.util.StringUtils;
    
    import java.util.Collection;
    
    public class SecurityUtils {
        public static Authentication getAuthentication() {
            return SecurityContextHolder.getContext().getAuthentication();
        }
    
    
        public static Collection<? extends GrantedAuthority> getAllPermission(){
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            return authorities;
        }
      //判断是否有权限
        public static boolean hasPermission(String permission){
            if(StringUtils.isEmpty(permission)){
                return false;
            }
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            boolean hasPermission = false;
            for(GrantedAuthority grantedAuthority : authorities){
                String authority = grantedAuthority.getAuthority();
                if(authority.equals(permission)){
                    hasPermission =true;
                }
            }
            return hasPermission;
        }
    
      //或取当前登录的用户信息
        public static User getUser() {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return (User) authentication.getPrincipal();
        }
    
    
        public static void logout(){
            SecurityContextHolder.clearContext();
        }
    
    }

    登录

    
    
    package com.liuchao.securitydemo.security.controller;

    import com.liuchao.securitydemo.security.entity.User;
    import com.liuchao.securitydemo.security.exception.MyException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.stereotype.Controller;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;

    @Controller
    public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @RequestMapping("/login")
    public String login(){
    return "login.html";
    }

    @RequestMapping("/userLogin")
    public String userLogin(@RequestParam("username")String userName,
    @RequestParam("password")String password,
    HttpServletRequest request) throws MyException {
    if(StringUtils.isEmpty(userName)){
    throw new MyException("没有输入用户名");
    }
    if(StringUtils.isEmpty(password)){
    throw new MyException("没有输入密码");
    }
    User user=new User();
    user.setUsername(userName);
    user.setPassword(password);

    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(userName,password);
    try{
            //拦截走springsecurity的登录和授权
    Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
    SecurityContextHolder.getContext().setAuthentication(authenticate);
    HttpSession session = request.getSession();
    session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); // 这个非常重要,否则验证后将无法登陆
    }catch (Exception e){
    e.printStackTrace();
    return "redirect:login-error?error=2";
    }
    return "redirect:index";
    }
    }
     

    配置错误页面

    @Configuration
    public class ErrorPageConfig implements ErrorPageRegistrar {
        private static final Logger logger = LoggerFactory.getLogger(ErrorPageConfig.class);
    
        @Override
        public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
            //1、按错误的类型显示错误的网页
    //        错误类型为404,找不到网页的,默认显示404.html网页
            ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404");
            //错误类型为500,表示服务器响应错误,默认显示500.html网页
            ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500");
            ErrorPage e403 = new ErrorPage(HttpStatus.FORBIDDEN, "/403");
            errorPageRegistry.addErrorPages(e404, e500,e403);
        }
    
    }
    package com.liuchao.securitydemo.security.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    @Controller
    public class IndexController {
    
    
        @RequestMapping(value="/index")
        public String index()  {
            return "index";
        }
    
        @RequestMapping(value="/login-error")
        public String loginError(String error)  {
            if("1".equals(error)){
                return  "login-error1";
            }
            return "login-error2";
        }
    
        @RequestMapping("/404")
        public String to404()  {
            return "404";
        }
        @RequestMapping("/403")
        public String to403()  {
            return "403";
        }
        @RequestMapping("/500")
        public String to500()  {
            return "500";
        }
    }

    接口增删改查的实例页面

    package com.liuchao.securitydemo.security.controller;
    
    import com.liuchao.securitydemo.security.entity.User;
    import com.liuchao.securitydemo.security.mapper.UserMapper;
    import com.liuchao.securitydemo.security.util.SecurityUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.HashMap;
    import java.util.List;
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserMapper userMapper;
    
        @RequestMapping(value = "/list")
        @PreAuthorize("hasAuthority('/user/list')")
        @ResponseBody
        public List login() {
            List<User> list =  userMapper.getAllUsers();
            return list;
        }
    
        @RequestMapping(value = "/update")
        @PreAuthorize("hasAuthority('/user/update')")
        @ResponseBody
        public HashMap<String, Object> update() {
            HashMap<String, Object> map = new HashMap<>();
            map.put("state","success");
            return map;
        }
    
    
        @RequestMapping(value = "/del")
        @PreAuthorize("hasAuthority('/user/del')")
        @ResponseBody
        public HashMap<String, Object> del() {
            HashMap<String, Object> map = new HashMap<>();
            map.put("state","success");
            return map;
        }
        @RequestMapping(value = "/add")
        @PreAuthorize("hasAuthority('/user/add')")
        @ResponseBody
        public HashMap<String, Object> add() {
            HashMap<String, Object> map = new HashMap<>();
            map.put("state","success");
            return map;
        }
    
        @RequestMapping(value = "/logout")
        public String logout() {
            SecurityUtils.logout();
            return "redirect:login";
        }
    
        @RequestMapping(value = "/info")
        @ResponseBody
        public User info() {
            return SecurityUtils.getUser();
        }
    }
  • 相关阅读:
    Struts2异常处理配置
    struts2支持的结果类型
    Project facet Java 1.8 is not supported by target runtime Apache Tomcat v7.0.
    net.paoding.analysis.exception.PaodingAnalysisException: dic home should not be a file, but a directory!
    struts.xml路径修改后的web配置
    struts.xml中的配置常量的含义
    Spring实战笔记
    2018第2周日
    新人替代旧人
    Web安全总结摘录
  • 原文地址:https://www.cnblogs.com/dkws/p/12156471.html
Copyright © 2011-2022 走看看