springboot-security

一、添加依赖

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

二、添加启动configuration 启动SpringSecurity过滤链

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.annotation.Resource;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/27 15:34
 */
@Configuration
@EnableWebSecurity //启动SpringSecurity过滤链
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private AuthUserDetailService authUserDetailService;

    //该方法的作用是代替之前的配置:<security:authentication-manager>
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("eric").password(new BCryptPasswordEncoder().encode("abc")).authorities("PRO_ADD");
        //相当于<security:authentication-provider user-service-ref="authUserDetailService">
        auth.userDetailsService(authUserDetailService).passwordEncoder(new BCryptPasswordEncoder());
    }
    //该方法的作用是代替之前的配置:<security:http>
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/manager/pro/del").hasAnyAuthority("Role_Del")
                .antMatchers("/manager/login").permitAll()
                .antMatchers("/manager/**")
                .fullyAuthenticated()
                .and()
                .formLogin().loginPage("/manager/login").failureHandler( new MyAuthenticationFailureHandler())
                .successHandler(new MyAuthenticationSuccessHandler())
                .and()
                .csrf().disable();


    }
}

同一错误页面转发

import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/27 16:41
 */
@Configuration
public class ErrorPageConfig {
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>(){
            //ErrorPage:定义错误页面
            //参数一 错误状态码
            //参数二 交给哪个请求处理
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/403"));
            }


        };
    }
}

用户权限赋予类

import cn.net.topnet.topfs.dynamicdb.MongodbTemplateContextHolder;
import cn.net.topnet.topfs.entities.Permissions;
import cn.net.topnet.topfs.entities.Users;
import cn.net.topnet.topfs.service.UserService;
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.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/28 10:03
 @Description: 实现了UserDetailsService接口中的loadUserByUsername方法
  * 执行登录,构建Authentication对象必须的信息,
  * 如果用户不存在,则抛出UsernameNotFoundException异常
 * @Param: [s]
 * @return: org.springframework.security.core.userdetails.UserDetails
 */
@Service
public class AuthUserDetailService implements UserDetailsService {
    @Resource
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        /**
         * @Author: Galen
         * @Description: 查询数据库,获取登录的用户信息
         **/
        MongodbTemplateContextHolder.setMongoDBTemplate("metadata");
        Users user = userService.findOneByUserName(s);
        if(user==null){
            throw new UsernameNotFoundException("用户名错误!");
        }
        MongodbTemplateContextHolder.setMongoDBTemplate("metadata");
        Set<Permissions> allPermissions = userService.findAllPermissionsByName(s);
        List<GrantedAuthority> authorities=new ArrayList<GrantedAuthority>();
        allPermissions.forEach(permissions -> {
            GrantedAuthority grantedAuthority=new SimpleGrantedAuthority(permissions.getSymbol());
            authorities.add(grantedAuthority);
        });
        user.setAuthorities(authorities);
        return user;
    }
}

验证失败拦截器

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/28 14:02
 */
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");
        Map result=new HashMap();
        if (exception instanceof BadCredentialsException ||
                exception instanceof UsernameNotFoundException) {
            result.put("error","账户名或者密码输入错误!");
        } else if (exception instanceof LockedException) {
            result.put("error","账户被锁定,请联系管理员!");
        } else if (exception instanceof CredentialsExpiredException) {
            result.put("error","密码过期,请联系管理员!");
        } else if (exception instanceof AccountExpiredException) {
            result.put("error","账户过期,请联系管理员!");
        } else if (exception instanceof DisabledException) {
            result.put("error","账户被禁用,请联系管理员!");
        } else {
            result.put("error","登录失败!");
        }
        ObjectMapper objectMapper=new ObjectMapper();
        response.setContentType("Text/json;charset=utf-8");
        response.getWriter().write(objectMapper.writeValueAsString(result));


    }
}

验证成功拦截器

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/28 14:37
 */
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        Map result=new HashMap();
        result.put("success",true);
        ObjectMapper objectMapper=new ObjectMapper();
        response.getWriter().write(objectMapper.writeValueAsString(result));
    }
}

用户实体类

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/27 17:26
 */
public class Users implements UserDetails {

    private String id;
    private String username;
    private String realName;
    private String password;
    private Date creatDate;
    private Date lastLoginTime;
    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private List<GrantedAuthority> authorities=new ArrayList<>();
    public String getId() {
        return id;
    }

    public void setAuthorities(List<GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Date getCreatDate() {
        return creatDate;
    }

    public void setCreatDate(Date creatDate) {
        this.creatDate = creatDate;
    }

    public Date getLastLoginTime() {
        return lastLoginTime;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    public void setAccountNonExpired(boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    public void setAccountNonLocked(boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }
}

controller

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Autor zhangjiawen
 * @Date: 2020/4/27 15:45
 */
@Controller
@RequestMapping("/manager")
public class SecurityController {

    @GetMapping("/index")
    public String index(){
        return "index";
    }

    @GetMapping("/pro/add")
    public String add(){
        return "add";
    }
    @GetMapping("/pro/update")
    public String update(){
        return "update";
    }
    @GetMapping("/pro/del")
    public String del(){
        return "del";
    }

    @GetMapping("/403")
    public String forbidden(){
        return "403";
    }
    @GetMapping("/login")
    public String login(){
        return "login";
    }

}

login.html

<!DOCTYPE html >
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/api/v1/manager/login" method="post">
账号:<input type="text" name="username"/>
    密码:<input type="text" name="password">
    <input type="submit" value="登录" />
    <span th:text="${error}"></span>

</form>

</body>
</html>

密码加密代码块

    @Override
    public Users insert(Users entity) {
        PasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        entity.setPassword(passwordEncoder.encode(entity.getPassword()));
        return mongoTemplate.insert(entity);
    }

 

posted @ 2020-04-29 16:11  valar-dohaeris  阅读(267)  评论(0编辑  收藏  举报