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

*********

例子可以在 码云上下载:https://gitee.com/aqu415/twboot.git

*********

概述

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

 

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

pom

搭建spring boot应用快捷的方式是在pom.xml中引入spring-boot-starter-parent 作为parent,如下:


	4.0.0
	com.tw
	twboot
	war
	0.0.1-SNAPSHOT
	twboot Maven Webapp
	http://maven.apache.org

	
		1.2.0
	

	
	
        org.springframework.boot
        spring-boot-starter-parent
        1.5.9.RELEASE
    

	
		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
		

		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		

		
		
			org.springframework.boot
			spring-boot-starter-security
		
		
		
		
			org.thymeleaf.extras
			thymeleaf-extras-springsecurity4
		

		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			${mybatis-spring-boot}
		

		
		
			junit
			junit
		

		
		
			commons-fileupload
			commons-fileupload
			1.3.1
		

		
			commons-io
			commons-io
			2.4
		
		
		
				javax.servlet
				servlet-api
				2.5
		

	

	
		twboot
	

 

application.yml

spring boot 中默认会获取classpath下的application.yml或者application.propertis文件作为配置文件

我用的前者

server:
  port: 80
spring:
  datasource:
    username: xyz
    password: xyz
    driver-class-name: oracle.jdbc.driver.OracleDriver
    url: jdbc:oracle:thin:@127.0.0.1:1521:XE
    dbcp2:
      max-idle: 10
      validation-query: select 1 from dual
  
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    
mybatis:
  type-aliases-package: com.tw.entity
  mapper-locations:
    - classpath:mapping/*.xml
        

 

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

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

Springboot启动类

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

 

package com.tw;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
@MapperScan("com.tw.dao")
public class StartApp extends SpringBootServletInitializer {
	public static void main(String[] args) {
		SpringApplication.run(StartApp.class);
	}

	//添加Tomcat支持
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(StartApp.class);
	}
}

 

上面的

@SpringBootApplication 表面这是一个springboot应用,

@MapperScan("com.tw.dao")  这个表示mybatis自动扫描dao接口的包名,

这个包下的接口会自动和spring boot配置项mapper-locations中的mybatis sql配置文件映射

 

Controller

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

 

@RestController

@Controller

我这里写一个简单的controller

package com.tw.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.servlet.ServletResponse;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CommonController {

	@PreAuthorize("hasRole('RRR')")
	@RequestMapping(value={"/","/home"})
    public String index() {
        return "home/home";
    }
	
	@RequestMapping("/login")
	public String login(Model model) {
		System.out.println("to login----");
		return "login/login";
	}
	
	@RequestMapping("/thymeleaf")
	public String test(Map map,ServletResponse response) throws UnsupportedEncodingException, IOException{
		map.put("name", "test");
		System.out.println("thymeleaf----");
		return "thymeleaf/hello2";
	}
	
	/**
	 * 功能描述:角色管理
	 * CHENY037 2017年11月29日
	 * @return
	 */
	@RequestMapping("/roleManage")
	@PreAuthorize("hasRole('ROLE_MANAGE')")
	public String roleManage(){
		return "home/role";
	}
	
}

spring security

自定义登录界面和自定义用户名密码校验

配置类:

package com.tw.config.Security;


import org.springframework.beans.factory.annotation.Autowired;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.password.PasswordEncoder;


/**
 * 配置类:
 * 配置security的登录页面和传递的参数,公共路径权限属性等
 * 
 * @author CHENY037
 *
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UrlUserService urlUserService;
    
    @Autowired
    SessionRegistry sessionRegistry;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
//                .antMatchers("/logout").permitAll()
                .antMatchers("/img/**").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/css/**").permitAll()
                .antMatchers("/bootstrap/**").permitAll()
                .antMatchers("/fonts/**").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                .anyRequest().authenticated()
                //登录相关
                .and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/home")
                .and().sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry)
                .and().and()
                .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .and()
                .httpBasic();
    }
    
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    	//这里是新增一个默认用户
        auth.inMemoryAuthentication().withUser("huahua").password("hello").roles("ADMIN");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(urlUserService).passwordEncoder(new PasswordEncoder() {

            @Override
            public String encode(CharSequence rawPassword) {
                return (String)rawPassword;//MD5Util.encode((String) rawPassword);
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
            	System.out.println(encodedPassword + "---" + (String)rawPassword);
                return encodedPassword.equals((String) rawPassword);
            }
        });
    }

    @Bean
    public SessionRegistry getSessionRegistry(){
        SessionRegistry sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }
}

自定义用户名密码校验类

package com.tw.config.Security;


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.User;
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 com.tw.dao.RoleDao;
import com.tw.dao.UserDao;
import com.tw.entity.role.TwRole;
import com.tw.entity.role.TwUser;

/**
 * 自定义用户名密码校验实现
 * 
 * @author CHANY037 2017-11
 *
 */
@Service
public class UrlUserService implements UserDetailsService {
	
    @Autowired
    UserDao userDao;
    
    @Autowired
    RoleDao roleDao;
    
    /**
     * employeeId 用户工号,在数据库中保证存储唯一
     */
    @Override
    public UserDetails loadUserByUsername(String employeeId) { //重写loadUserByUsername 方法获得 userdetails 类型用户

        TwUser user = userDao.findByEmployeeId(employeeId);
        
        if(user == null){
        	throw new UsernameNotFoundException(employeeId + " do not exist!");
        } else {
        	System.out.println(user.getPassword() + " --pw-- ");
            List roles = roleDao.findRoleByEmployeeId(employeeId);
            List grantedAuthorities = new ArrayList();
            
            //写入用户的角色  ***  切记 由于框架原因 角色名称要以 ROLE_ 开头 **** 血泪史 ****
            //源码:org.springframework.security.access.expression.SecurityExpressionRoot hasAnyRole()
            for (TwRole role : roles) {
                if (role != null && role.getRoleName() != null) {
                	SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRoleCode());
                    grantedAuthorities.add(grantedAuthority);
                }
            }
            org.springframework.security.core.userdetails.User uu = new User(employeeId, user.getPassword(), grantedAuthorities);
            return uu;
        }
    }
}


登录界面html 即 上面

CommonController 里定义的login方法返回的视图
 





Login











 

你可能感兴趣的:(Spring)