SpringBoot + Security 自定义登录界面 数据库动态管理用户和权限 记住密码 退出登录


Security的基本介绍搜搜别的博客看吧,我是来贴代码的(如果是新手,一定要多看看基本介绍,搭建,配置等)


最重要的Security配置代码

package com.**.config;


import java.io.IOException;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;


import com.**.core.service.CustomerUserService;


@Configuration
@EnableWebSecurity    //打开SpringSecurity的web支持
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
    UserDetailsService customerUserService(){
        return new CustomerUserService();
    }

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在内存中创建一个ADMIN角色的用户
//        auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder())  //5.0以上的security版本需要一个密码编码器 需要自定义
//                .withUser("testoc").password("0bf1e4984cd85c0eb227856324b72901").roles("supperManager");
        //此处可以创建多个用户
//        auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder())
//                .withUser("demo").password("demo").roles("USER");

        //使用数据库管理用户

        //customerUserService()是获取数据库动态用户和角色数据    new MyPasswordEncoder()提供密码的MD5加密对比

        auth.userDetailsService(customerUserService()).passwordEncoder(new MyPasswordEncoder());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/assets/**","/login").permitAll()     //对项目主路径和css,js静态资源放行
        .anyRequest().authenticated()       //其他路径进行权限验证
                .and()
                .logout().logoutSuccessUrl("/login?logout")  
.deleteCookies("remember-me").permitAll()
                .logoutSuccessUrl("/login").permitAll()       //对注销放行
                .and().rememberMe().rememberMeParameter("remember-me").tokenValiditySeconds(1209600)//记住密码时效
                .and()
                .formLogin().loginPage("/login").successHandler(new AuthenticationSuccessHandler() {//登陆成功后操作
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2)
                            throws IOException, ServletException {
                        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                        if (principal != null && principal instanceof UserDetails) {
                            UserDetails user = (UserDetails) principal;
                            System.out.println("loginUser:"+user.getUsername());
                            //维护在session中
                            arg0.getSession().setAttribute("userDetail", user);
                            arg1.sendRedirect("/index.do");
                        } 
                    }
                }).permitAll();//.loginPage("/login")
    }


    @Override
    public void configure(WebSecurity web) throws Exception{
//        super.configure(web);
        //忽略静态资源的权限拦截
        web.ignoring().antMatchers("/assets/**","**/jsp/**");
    }

}




package com.**.config;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import com.**.RunMain;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RunMain.class);
}

}



提供密码对比的代码

package com.**.config;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.**.core.service.CustomerUserService;
import com.**.core.util.MD5Util;
public class MyPasswordEncoder implements PasswordEncoder {
    public String encode(CharSequence rawPassword) {
        //加密方法
        return rawPassword.toString();
    }
public boolean matches(CharSequence rawPassword, String encodedPassword) {
    try {//个人方法将密码和用户id加密   大家可以自定义
    Integer id = CustomerUserService.getUser().getId();
    if(MD5Util.checkPasswordWithSalt(rawPassword.toString(),encodedPassword, id)) {//参数(页面明文密码,数据库加密密码,用户id)
    return true;
    }
    return false;
    }catch(Exception e){
    return false;
    }
    }
public static void main(String[] args) {
System.out.println(MD5Util.getMD5EncodedPasswordWithSalt("0bf1e4984cd85c0eb227856324b72901",33));
}

}





动态获取用户数据代码

package com.**.core.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
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 com.**.core.entity.Role;
import com.**.core.entity.User;
import com.**.core.mapper.RoleMapper;
import com.**.core.mapper.UserMapper;
//继承UserDetailsService 会自动找到loadUserByUsername方法获取动态数据
public class CustomerUserService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleMapper roleMapper;
static User user;
    public static User getUser() {
return user;
}
public static void setUser(User user) {
CustomerUserService.user = user;
}
@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User sysUser = userMapper.loadUserByUsername(username);
    if(sysUser == null){
    throw new UsernameNotFoundException("用户名不存在");
    }
    user = sysUser;
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    Role role = roleMapper.selectByPrimaryKey(new BigDecimal(sysUser.getRoleid()));
    sysUser.setRole(role);//重点"ROLE_"+role.getCode()   ROLE_必须加  判断权限会以ROLE_开头判断  看看源码就可以理解
    authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getCode()));
        return new org.springframework.security.core.userdetails.User(sysUser.getLoginName(),sysUser.getPassword(),authorities);
    }

}




接下来贴前端页面代码


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page isELIgnored ="false" %>
<%@ include file="/page/common/pub.jsp" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Login page</title>
        <link href="<c:url value='${basePath}assets/pages/css/bootstrap.css' />"  rel="stylesheet"></link>
<%--         <link href="<c:url value='${basePath}assets/pages/css/app.css' />" rel="stylesheet"></link> --%>
        <link href="${basePath}assets/pages/css/ynz/common/static.css?version=20170817024514" rel='stylesheet' type='text/css'  />
<link href="${basePath}assets/pages/css/ynz/login/login.css?version=20170817024514" rel='stylesheet' type='text/css'  />
        <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css" />
        <style>
.input-group{
      line-height: 60px;
          width: 300px;
}
</style>
    </head>


    <body>
        <div id="mainWrapper">
            <div class="login-container">
                <div class="login-card">
                    <div class="login-form" style="position: absolute;left: 45%;top: 35%;">
                        <form action="/login" method="POST" class="form-horizontal" id="loginForm">
                            <c:if test="${param.error != null}">
                                <div class="alert alert-danger">
                                    <p>Invalid username and password.</p>
                                </div>
                            </c:if>
                            <c:if test="${param.logout != null}">
                                <div class="alert alert-success">
                                    <p>You have been logged out successfully.</p>
                                </div>
                            </c:if>
                            <div class="input-group input-sm">
                                <label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
                                <input type="text" class="form-control" id="username" name="username" placeholder="Enter Username" required>
                            </div>
                            <div class="input-group input-sm">
                                <label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label> 
                                <input type="password" class="form-control" id="password"  name="password" placeholder="Enter Password" required>
                            </div>
                            <input type="hidden" name="${_csrf.parameterName}"   value="${_csrf.token}" />
                            <div id="" class="choice">
                            <input type="checkbox" name="remember-me">记住密码
<!-- <i class="remberPass" id="remberPass"></i><span>记住密码</span> -->
</div>
                            <div class="form-actions" style="margin-left: 20px;width: 250px">
                                <input type="submit" id="loginSys" class="btn btn-block btn-primary btn-default" value="登录">
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </body>

</html>



退出登录

<form action="/logout" method="POST">
<input type="submit" value="退出登录">
<input type="hidden" name="${_csrf.parameterName}"   value="${_csrf.token}" />

</form>



登录是自定义页面,所以转页面是用的get方法

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage() {
        return "login/login";

    }

提交登录是post

退出登录是security的方法,用form表单post提交

猜你喜欢

转载自blog.csdn.net/qq_33545171/article/details/80679899