spring boot 2.1.4整合spring Security实现自定义的登录

总体项目结构
项目结构
数据库的设计
基于navicat下的数据库表预览
1. 首先在pom.xml中添加对应的依赖

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

2.新建一个security的package

2.1新建一个DatabaseUserDetailService.java,这个代码主要是实现自定义登录的权限控制和登录细节实现。


import com.travellerManager.sys.mapper.UserMapper;
import com.travellerManager.sys.pojo.Permission;
import com.travellerManager.sys.pojo.Role;
import com.travellerManager.sys.pojo.User;
import netscape.security.Privilege;
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 java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/*继承security提供的UserDetailsService接口*/
public class DatabaseUserDetailService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper; /*登录对应的数据访问层*/

	/*重新实现方法loadUserByUsername(String username)*/
    public UserDetails loadUserByUsername(String username) {
        User user ;
        /*由于返回的是UserDetails对象,所以需要对我们的简单类进行转换*/
        org.springframework.security.core.userdetails.User _user = null;
        try {
        	/*对应的数据层方法*/
            user = userMapper.findUserByUsername(username);
            // 将自己的user对象封装为UserDetails,对应的User构造方法中需要的一些相关的参数-可以自己baidu,最后一参数是对应的权限
            _user = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getStatus() == 0 ? false : true, true, true, true, getAuthority(user.getRoles()));
        } catch (Exception e) {
            e.printStackTrace();
        }
       /*返回包装好的user*/ 
       return _user;
    }

    //作用就是返回一个List集合,集合中装入的是角色描述
    //注意返回的权限必须是GrantedAuthority的子类
    private final List<? extends GrantedAuthority> getAuthority(final List<Role> roles) {
        return getGrantedAuthorities(getPrivileges(roles));
    }
	
	//具体获取权限的方法
    private final List<String> getPrivileges(final Collection<Role> roles) {
        final List<String> privileges = new ArrayList<>();
        final List<Permission> collection = new ArrayList<>();
        //将所有的权限放到collection中
        for (final Role role : roles) {
            collection.addAll(role.getPermissions());
        }
        for (final Permission item : collection) {
            privileges.add(item.getPermissionName());
        }

        return privileges;
    }

	//将自己的权限通过SimpleGrantedAuthority包装
    private final List<GrantedAuthority> getGrantedAuthorities(final List<String> privileges) {
        final List<GrantedAuthority> authorities = new ArrayList<>();
        for (final String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }
}

2.2 添加spring security的配置类


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

//这两个注解缺一不可
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	//配置spring的类装载实例化
    @Bean
    DatabaseUserDetailService userDetailService() {
        return new DatabaseUserDetailService();
    }

    /**
     *     5.1.2自动加密!!!!!!!!!
     */
//    @Bean
//    public BCryptPasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }

    //重写参数为HttpSecurity的configure方法,配置拦截策略
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //自定义登陆页面
                .formLogin()
                // 前端所访问的登录页面
                .loginPage("/login")
                // 提交登录信息交由处理的路径--交由security处理,自己不实现
                .loginProcessingUrl("/doLogin")
                //登陆成功后跳转的页面
                .defaultSuccessUrl("/index").permitAll()
                //登陆失败或无权限跳转页面
                .failureUrl("/failure")
                //其他所有页面必须验证后才可以访问
                .and().authorizeRequests().antMatchers("/login", "/plugins/**").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable();

        // 默认注销/logout
        http.logout()
                // 成功跳转地址
                .logoutSuccessUrl("/login");

    }

	/*对权限进行配置*/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService());
    }

}

对应的/login的controller

@RequestMapping("/login")        
public String goIndex() {
    //返回登录界面
    return "login";
}

对应的前端登录,注意用户名name必须是username,密码的name必须是password

<form action="/doLogin" method="post">
				<div class="form-group has-feedback">
					<input type="text" name="username" class="form-control"
						placeholder="用户名"> <span
						class="glyphicon glyphicon-envelope form-control-feedback"></span>
				</div>
				<div class="form-group has-feedback">
					<input type="password" name="password" class="form-control"
						placeholder="密码"> <span
						class="glyphicon glyphicon-lock form-control-feedback"></span>
				</div>
				<div class="row">
					<div class="col-xs-8">
						<div class="checkbox icheck">
							<label><input type="checkbox"> 记住 下次自动登录</label>
						</div>
					</div>
					<!-- /.col -->
					<div class="col-xs-4">
						<button type="submit" class="btn btn-primary btn-block btn-flat">登录</button>
					</div>
					<!-- /.col -->
				</div>
			</form>

3.错误处理页面
配置相应的403\404\500错误处理页面

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class ErrorPageConfig implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404");
        // TODO Auto-generated method stub
        ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500");

        ErrorPage e403 = new ErrorPage(HttpStatus.FORBIDDEN, "/403");
        registry.addErrorPages(e404, e500, e403);
    }

}

在controller包下新建一个ErrorController.java

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

@Controller
public class ErrorController {
    @RequestMapping("/404")
    public String error_404() {
        return "404";
    }

    @RequestMapping("/500")
    public String error_500() {
        return "500";
    }

    @RequestMapping("/403")
    public String error_403() {
        return "403";
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值