spring boot + mybatis + spring security(自定义登录界面)环境搭建

概述

在前不久用了spring boot、mybatis、spring security搭建了一个工程,中间经历了各种坑,最后得到一条经验:spring的文档很详细,入门最好以官方文档为准。

这里讲的是以mav作为依赖管理工具

pom

搭建spring boot应用快捷的方式是在pom.xml中引入spring-boot-starter-parent 作为parent,如下:
[java]  view plain  copy
  1. "http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.     4.0.0  
  4.     com.tw  
  5.     twboot  
  6.     war  
  7.     0.0.1-SNAPSHOT  
  8.     twboot Maven Webapp  
  9.     http://maven.apache.org  
  10.   
  11.       
  12.         1.2.0  
  13.       
  14.   
  15.       
  16.       
  17.         org.springframework.boot  
  18.         spring-boot-starter-parent  
  19.         1.5.9.RELEASE  
  20.       
  21.   
  22.       
  23.           
  24.           
  25.             org.springframework.boot  
  26.             spring-boot-starter-thymeleaf  
  27.           
  28.   
  29.           
  30.           
  31.             org.springframework.boot  
  32.             spring-boot-starter-test  
  33.             test  
  34.           
  35.   
  36.           
  37.           
  38.             org.springframework.boot  
  39.             spring-boot-starter-security  
  40.           
  41.           
  42.           
  43.           
  44.             org.thymeleaf.extras  
  45.             thymeleaf-extras-springsecurity4  
  46.           
  47.   
  48.           
  49.           
  50.             org.mybatis.spring.boot  
  51.             mybatis-spring-boot-starter  
  52.             ${mybatis-spring-boot}  
  53.           
  54.   
  55.           
  56.           
  57.             junit  
  58.             junit  
  59.           
  60.   
  61.           
  62.           
  63.             commons-fileupload  
  64.             commons-fileupload  
  65.             1.3.1  
  66.           
  67.   
  68.           
  69.             commons-io  
  70.             commons-io  
  71.             2.4  
  72.           
  73.           
  74.           
  75.                 javax.servlet  
  76.                 servlet-api  
  77.                 2.5  
  78.           
  79.   
  80.       
  81.   
  82.       
  83.         twboot  
  84.       
  85.   

application.yml

spring boot 中默认会获取classpath下的application.yml或者application.propertis文件作为配置文件
我用的前者
[java]  view plain  copy
  1. server:  
  2.   port: 80  
  3. spring:  
  4.   datasource:  
  5.     username: xyz  
  6.     password: xyz  
  7.     driver-class-name: oracle.jdbc.driver.OracleDriver  
  8.     url: jdbc:oracle:thin:@127.0.0.1:1521:XE  
  9.     dbcp2:  
  10.       max-idle: 10  
  11.       validation-query: select 1 from dual  
  12.     
  13.   thymeleaf:  
  14.     cache: false  
  15.     prefix: classpath:/templates/  
  16.     suffix: .html  
  17.       
  18. mybatis:  
  19.   type-aliases-package: com.tw.entity  
  20.   mapper-locations:  
  21.     - classpath:mapping/*.xml  
  22.           

上面的server.port 表示spring boot内置tomcat启动的端口是80,view层显示用的thymeleaf模板,模板前后缀也在配置文件中定义,这个和spring mvc那种配置类似;

另工程中只用用一种view表示方式,用了thymeleaf就不要用jsp了,网上说的两种模板解析链是有先后处理顺序的,也就是说是有优先级;

Springboot启动类

在我们的package最顶层新建一个继承SpringBootServletInitializer的类(内容如下),这样一个spring boot项目就搭建好了

[java]  view plain  copy
  1. package com.tw;  
  2.   
  3. import org.mybatis.spring.annotation.MapperScan;  
  4. import org.springframework.boot.SpringApplication;  
  5. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  6. import org.springframework.boot.builder.SpringApplicationBuilder;  
  7. import org.springframework.boot.web.support.SpringBootServletInitializer;  
  8.   
  9. @SpringBootApplication  
  10. @MapperScan("com.tw.dao")  
  11. public class StartApp extends SpringBootServletInitializer {  
  12.     public static void main(String[] args) {  
  13.         SpringApplication.run(StartApp.class);  
  14.     }  
  15.   
  16.     //添加Tomcat支持  
  17.     @Override  
  18.     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
  19.         return application.sources(StartApp.class);  
  20.     }  
  21. }  

上面的
@SpringBootApplication 表面这是一个springboot应用,
@MapperScan("com.tw.dao")  这个表示 mybatis自动扫描dao接口的包名
这个包下的接口会自动和spring boot配置项mapper-locations中的mybatis sql配置文件映射

Controller

在spring boot中controller分为两类,一种是返回数据的Controller,一种是返回视图的Controller,分别注解是

@RestController
@Controller
我这里写一个简单的controller
[java]  view plain  copy
  1. package com.tw.controller;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.util.Map;  
  6.   
  7. import javax.servlet.ServletResponse;  
  8.   
  9. import org.springframework.security.access.prepost.PreAuthorize;  
  10. import org.springframework.stereotype.Controller;  
  11. import org.springframework.ui.Model;  
  12. import org.springframework.web.bind.annotation.RequestMapping;  
  13.   
  14. @Controller  
  15. public class CommonController {  
  16.   
  17.     @PreAuthorize("hasRole('RRR')")  
  18.     @RequestMapping(value={"/","/home"})  
  19.     public String index() {  
  20.         return "home/home";  
  21.     }  
  22.       
  23.     @RequestMapping("/login")  
  24.     public String login(Model model) {  
  25.         System.out.println("to login----");  
  26.         return "login/login";  
  27.     }  
  28.       
  29.     @RequestMapping("/thymeleaf")  
  30.     public String test(Map map,ServletResponse response) throws UnsupportedEncodingException, IOException{  
  31.         map.put("name""test");  
  32.         System.out.println("thymeleaf----");  
  33.         return "thymeleaf/hello2";  
  34.     }  
  35.       
  36.     /** 
  37.      * 功能描述:角色管理 
  38.      * CHENY037 2017年11月29日 
  39.      * @return 
  40.      */  
  41.     @RequestMapping("/roleManage")  
  42.     @PreAuthorize("hasRole('ROLE_MANAGE')")  
  43.     public String roleManage(){  
  44.         return "home/role";  
  45.     }  
  46.       
  47. }  

spring security

自定义登录界面和自定义用户名密码校验
配置类:
[java]  view plain  copy
  1. package com.tw.config.Security;  
  2.   
  3.   
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.context.annotation.Bean;  
  6. import org.springframework.context.annotation.Configuration;  
  7. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  8. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  9. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  10. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  11. import org.springframework.security.core.session.SessionRegistry;  
  12. import org.springframework.security.core.session.SessionRegistryImpl;  
  13. import org.springframework.security.crypto.password.PasswordEncoder;  
  14.   
  15.   
  16. /** 
  17.  * 配置类: 
  18.  * 配置security的登录页面和传递的参数,公共路径权限属性等 
  19.  *  
  20.  * @author CHENY037 
  21.  * 
  22.  */  
  23. @Configuration  
  24. @EnableWebSecurity  
  25. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
  26.   
  27.     @Autowired  
  28.     private UrlUserService urlUserService;  
  29.       
  30.     @Autowired  
  31.     SessionRegistry sessionRegistry;  
  32.   
  33.     @Override  
  34.     protected void configure(HttpSecurity http) throws Exception {  
  35.         http.csrf().disable()  
  36.                 .authorizeRequests()  
  37.                 .antMatchers("/login").permitAll()  
  38. //                .antMatchers("/logout").permitAll()  
  39.                 .antMatchers("/img/**").permitAll()  
  40.                 .antMatchers("/js/**").permitAll()  
  41.                 .antMatchers("/css/**").permitAll()  
  42.                 .antMatchers("/bootstrap/**").permitAll()  
  43.                 .antMatchers("/fonts/**").permitAll()  
  44.                 .antMatchers("/favicon.ico").permitAll()  
  45.                 .anyRequest().authenticated()  
  46.                 //登录相关  
  47.                 .and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/home")  
  48.                 .and().sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry)  
  49.                 .and().and()  
  50.                 .logout()  
  51.                 .invalidateHttpSession(true)  
  52.                 .clearAuthentication(true)  
  53.                 .and()  
  54.                 .httpBasic();  
  55.     }  
  56.       
  57.       
  58.     @Autowired  
  59.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {  
  60.         //这里是新增一个默认用户  
  61.         auth.inMemoryAuthentication().withUser("huahua").password("hello").roles("ADMIN");  
  62.     }  
  63.   
  64.     @Override  
  65.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {  
  66.         auth.userDetailsService(urlUserService).passwordEncoder(new PasswordEncoder() {  
  67.   
  68.             @Override  
  69.             public String encode(CharSequence rawPassword) {  
  70.                 return (String)rawPassword;//MD5Util.encode((String) rawPassword);  
  71.             }  
  72.   
  73.             @Override  
  74.             public boolean matches(CharSequence rawPassword, String encodedPassword) {  
  75.                 System.out.println(encodedPassword + "---" + (String)rawPassword);  
  76.                 return encodedPassword.equals((String) rawPassword);  
  77.             }  
  78.         });  
  79.     }  
  80.   
  81.     @Bean  
  82.     public SessionRegistry getSessionRegistry(){  
  83.         SessionRegistry sessionRegistry = new SessionRegistryImpl();  
  84.         return sessionRegistry;  
  85.     }  
  86. }  
自定义用户名密码校验类
[java]  view plain  copy
  1. package com.tw.config.Security;  
  2.   
  3.   
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.security.core.GrantedAuthority;  
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  10. import org.springframework.security.core.userdetails.User;  
  11. import org.springframework.security.core.userdetails.UserDetails;  
  12. import org.springframework.security.core.userdetails.UserDetailsService;  
  13. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  14. import org.springframework.stereotype.Service;  
  15.   
  16. import com.tw.dao.RoleDao;  
  17. import com.tw.dao.UserDao;  
  18. import com.tw.entity.role.TwRole;  
  19. import com.tw.entity.role.TwUser;  
  20.   
  21. /** 
  22.  * 自定义用户名密码校验实现 
  23.  *  
  24.  * @author CHANY037 2017-11 
  25.  * 
  26.  */  
  27. @Service  
  28. public class UrlUserService implements UserDetailsService {  
  29.       
  30.     @Autowired  
  31.     UserDao userDao;  
  32.       
  33.     @Autowired  
  34.     RoleDao roleDao;  
  35.       
  36.     /** 
  37.      * employeeId 用户工号,在数据库中保证存储唯一 
  38.      */  
  39.     @Override  
  40.     public UserDetails loadUserByUsername(String employeeId) { //重写loadUserByUsername 方法获得 userdetails 类型用户  
  41.   
  42.         TwUser user = userDao.findByEmployeeId(employeeId);  
  43.           
  44.         if(user == null){  
  45.             throw new UsernameNotFoundException(employeeId + " do not exist!");  
  46.         } else {  
  47.             System.out.println(user.getPassword() + " --pw-- ");  
  48.             List roles = roleDao.findRoleByEmployeeId(employeeId);  
  49.             List grantedAuthorities = new ArrayList();  
  50.               
  51.             //写入用户的角色  ***  切记 由于框架原因 角色名称要以 ROLE_ 开头 **** 血泪史 ****  
  52.             //源码:org.springframework.security.access.expression.SecurityExpressionRoot hasAnyRole()  
  53.             for (TwRole role : roles) {  
  54.                 if (role != null && role.getRoleName() != null) {  
  55.                     SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRoleCode());  
  56.                     grantedAuthorities.add(grantedAuthority);  
  57.                 }  
  58.             }  
  59.             org.springframework.security.core.userdetails.User uu = new User(employeeId, user.getPassword(), grantedAuthorities);  
  60.             return uu;  
  61.         }  
  62.     }  
  63. }  

登录界面html 即 上面
[java]  view plain  copy
  1. CommonController 里定义的login方法返回的视图  
[java]  view plain  copy
  1.   
[java]  view plain  copy
  1.   
  2. "en" class="no-js"   
  3.          xmlns="http://www.w3.org/1999/xhtml"   
  4.          xmlns:th="http://www.thymeleaf.org"  
  5.          xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">  
  6.   
  7. "UTF-8"/>  
  8.   
  9. Login  
  10. "viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
  11. "X-UA-Compatible" content="IE=edge,chrome=1" />  
  12.   
  13. "stylesheet" th:href="@{bootstrap/css/bootstrap.min.css}"/>  
  14. "@{js/jquery.min.js}">  
  15. "@{bootstrap/js/bootstrap.min.js}">  
  16.   
  17.   
  18.   
  19. "background: url(img/login.jpg);width: 98%;">  
  20.   
  21. "margin-top: 150px;margin-left: 800px;margin-bottom: 160px;" >  
  22.   
  23.     class="form-horizontal" method="post" th:action="@{/login}">  
  24.             class="form-group">  
  25.                 for="inputEmail3" class="col-sm-2 control-label">用户名  
  26.                 class="col-sm-10">"off" type="text" class="form-control" name="username" />
  
  •             
  •   
  •             class="form-group">  
  •                 for="inputPassword3" class="col-sm-2 control-label">密码  
  •                 class="col-sm-10">  
  •                 "text" class="form-control" name="password" οnfοcus="this.type='password'"/>  
  •                 
  •   
  •             
  •   
  •             class="form-group">  
  •                 class="col-sm-offset-2 col-sm-10">  
  •                     class="checkbox">  
  •                           />Remember me  
  •                     
  •   
  •                 
  •   
  •             
  •   
  •             class="form-group">  
  •                 class="col-sm-offset-2 col-sm-10">  
  •                      "submit" class="btn btn-default">登录  
  •                 
  •   
  •             
  •   
  •       
  •   
  •   
  •   
  • "common/footer :: footer">
  •   
  •   
  •   
  •  
  • 你可能感兴趣的:(spring boot + mybatis + spring security(自定义登录界面)环境搭建)