spring-boot集成spring-security较简洁和实用方案

前端时间公司要做一个新的小产品,突发奇想用了spring-boot加spring-security做了登录验证,过程中总感觉晚上的资料很散,索性就整理了一下,当然我感觉我的也不全哈哈哈,基本够用。

先从最开始说起,引入maven依赖包写入pom文件:

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

 

 

 

由于这次我使用的是spring-boot 1.3.6版本,所以所有范例都已此版本为基础。

废话不说,上源码。

现在启动类同包的地方建立spring security的配置类如:

package com.shineyue;

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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.shineyue.security.CustomUserDetailsService;
import com.shineyue.security.ShineyueAuthenticationProvider;
/**
 * 集成spring-security
 * @author zml
 *
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
	@Autowired
	private CustomUserDetailsService customUserDetailsService;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/login").permitAll()//1根路径和/login路径不拦截
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login") //2登陆页面
                .defaultSuccessUrl("/home") //3登陆成功转向该页面
                .permitAll()
                .and()
                .logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true)
                .permitAll();
    }

    //4
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		
    		auth.authenticationProvider(new ShineyueAuthenticationProvider(customUserDetailsService));
    		auth.eraseCredentials(true);
    }
    //5忽略静态资源的拦截
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/static/**","/informationFeedback","/js/**","/error");
    }
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
    	return new BCryptPasswordEncoder(4); 
    }

}

其中的ShineyueAuthenticationProvider是我们处理登录信息基本逻辑的地方,代码:

package com.shineyue.security;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class ShineyueAuthenticationProvider implements AuthenticationProvider {

	private UserDetailsService userDetailsService;
	
	
	public ShineyueAuthenticationProvider(UserDetailsService userDetailsService){
		this.userDetailsService=userDetailsService;
	}
	
	@Override
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
		UserDetails userDetails =userDetailsService.loadUserByUsername(token.getName());
		if(userDetails.getUsername()==null||userDetails.getUsername().equals("")){
			throw new UsernameNotFoundException("用户不存在");
		}else if(!userDetails.isEnabled()){
			throw new DisabledException("用户已被禁用");
		}
		String encryptedPassword = userDetails.getPassword();   // 数据库用户的密码,一般都是加密过的
		String inputPassword = (String) token.getCredentials(); // 用户输入的密码
		if(!encryptedPassword.equals(inputPassword)){
			throw new BadCredentialsException("密码无效,请重新输入");
		}
		return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return UsernamePasswordAuthenticationToken.class.equals(authentication);
	}

}

 

customUserDetailsService对象是去数据库查询登录信息的具体实现,如代码:

 

package com.shineyue.security;

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

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.SLF4JLogFactory;
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.Component;

import com.shineyue.JkViewWebSocket;
import com.shineyue.calldb.CallDbException;
import com.shineyue.calldb.DbMethod;
import com.shineyue.calldb.sql.NoSuchColumnException;
import com.shineyue.calldb.sql.Row;
import com.shineyue.calldb.sql.UnsupportedConversionException;
import com.shineyue.jkjk.bean.UserInfo;
@Component
public class CustomUserDetailsService implements UserDetailsService {
	
	
	
	
	private static final Log log = SLF4JLogFactory.getLog(CustomUserDetailsService.class);
	/**
	 * arg0 登录时的用户名
	 */
	@Resource(name="dbTmpMethod")
	private DbMethod dbTmpMethod;
	@Override
	public UserDetails loadUserByUsername(String arg0)
			throws UsernameNotFoundException {
		System.out.println("arg0"+arg0);
		//在这里执行查询逻辑返回用户信息
		SUser su = new SUser();
		if(dbTmpMethod==null){
			log.error("login error -->dbTmpMethod is null");
		}else{
			UserInfo ui =new UserInfo();
			ui.setName(arg0);
			//这下面的代码是我们自定义的数据库查询API,大家不必使用,使用我们常见的mybatis即可 将查询出的信息放入su对象中返回SecurityUser对象
			try {
				List<Row> l =dbTmpMethod.Open("JKJK_COMMON_GET_USERINFO", ui);
				if(l.size()==1){
					su.setDob(new Date());
					su.setEmail("hahah@163.com");
					su.setId(l.get(0).getDefInt("uid"));
					su.setName(l.get(0).getTrimString("name"));
					su.setPassword(l.get(0).getTrimString("password"));
					su.setMianAuth(l.get(0).getTrimString("auth"));
					su.setState(l.get(0).getDefInt("state"));
					String[] jgqx_arr=l.get(0).getTrimString("jgqx").split(",");
					if(jgqx_arr.length>0){
						List<String> l_jgqx=Arrays.asList(jgqx_arr);
						su.setJgqx(l_jgqx);
					}
				}
				
				log.info("login user:"+l.get(0).getTrimString("name"));
			} catch (CallDbException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchColumnException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedConversionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//System.out.println("dbTmpMethod is not null");
		}
		
		
		
		return new SecurityUser(su);
	}

}

 

 

这3个类基本上就是完成登录的核心,当然我们还需要一些对于用户信息进行处理类。

比如:

package com.shineyue.security;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class SUser implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7019867470266738718L;
	private int id;
	private String name;
	private String email;
	private String password;
	private Date dob;
	private String mianAuth;
	private int state;
	private Set<SRole> sRoles = new HashSet<SRole>(0);
	private List<String> jgqx=new ArrayList<String>();
	public SUser(){
		
	}
	
	
	public List<String> getJgqx() {
		return jgqx;
	}
	public void setJgqx(List<String> jgqx) {
		this.jgqx = jgqx;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Date getDob() {
		return dob;
	}
	public void setDob(Date dob) {
		this.dob = dob;
	}
	public Set<SRole> getsRoles() {
		return sRoles;
	}
	public void setsRoles(Set<SRole> sRoles) {
		this.sRoles = sRoles;
	}
	public static long getSerialversionuid() {
		return serialVersionUID;
	}
	public String getMianAuth() {
		return mianAuth;
	}
	public void setMianAuth(String mianAuth) {
		this.mianAuth = mianAuth;
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	
}

 

 

 

package com.shineyue.security;

public class SRole {
	private int id;
	private String name;
	private int uid;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	
}

 

 

package com.shineyue.security;

import java.util.ArrayList;
import java.util.Collection;

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



public class SecurityUser implements UserDetails {
	private SUser user;
	/**
	 * 
	 */
	private static final long serialVersionUID = -1623385418837308233L;
	public SecurityUser(SUser u){
		this.user=u;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		//放入用户的权限和角色信息
		SimpleGrantedAuthority authority= new SimpleGrantedAuthority("auth:"+this.user.getMianAuth());
		authorities.add(authority);
		authorities.add(authority1);
		return authorities;
	}

	@Override
	public String getPassword() {
		// TODO Auto-generated method stub
		return this.user.getPassword();
	}

	@Override
	public String getUsername() {
		// TODO Auto-generated method stub
		return this.user.getName();
	}

	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isEnabled() {
		if(this.user.getState()==2){
			return false;
		}else{
			return true;
		}
		
	}

}

 

 

然后就是在一个Controller类中写入login方法用于登录时信息的返回和状态更改具体代码如下:

	@RequestMapping("login")
	public String login(@RequestParam(value="error", required=false) String error,
            @RequestParam(value="logout", required=false) String logout,HttpServletRequest request, HttpServletResponse response,ModelMap model){
		if (error != null) {
			
			 AuthenticationException ex = (AuthenticationException)request.getSession()
			          .getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
			model.put("error", ex.getMessage());
        } else if (logout != null) {
            model.put("logout", "Logout successful");
        }
		return "login";

	}

 

 

之后就是写一个登录页,别忘了等于的用户名和密码控件名词必须用username和password

转载于:https://my.oschina.net/u/252181/blog/1501386

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值