demo工程接上篇,本文介绍如何给rest服务添加安全机制。 ##加入security依赖 在POM文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
重新启动应用,访问http://localhost:8080/user ,会弹出要求输入用户名密码的输入框。用户名输入user,密码在输出日志里面找到这一段。
Using default security password: f03c3a81-1ba0-4e72-9f52-4d0906a22853
其中 f03c3a81-1ba0-4e72-9f52-4d0906a22853 就是密码,每次启动都会随机生成。 ##添加security配置 自动生成的用户名密码显然不能用于生产环境,spring security也支持自定义用户账户,新建SecurityConfig类继承自WebSecurityConfigurerAdapter。 ###内存用户 在SecurityConfig中加入以下代码。
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("zhm").password("1q2w3e4r").roles("USER").and()
.withUser("admin").password("1q2w3e4r").roles("USER","ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.logout().and()
.authorizeRequests()
.anyRequest().fullyAuthenticated().and()
.csrf().disable();
// @formatter:on
}
重启应用就可以使用zhm/1q2w3e4r或者admin/1q2w3e4r登录了。 ###数据库用户 当然用户账户还可以基于数据库存储,具体实现如下。
package com.zhm.config;
import com.zhm.repository.UserInfoRepository;
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;
/**
* Created by zhm on 16-10-18.
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserInfoRepository repository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.logout().and()
.authorizeRequests()
.anyRequest().fullyAuthenticated().and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
public MyAuthenticationProvider authenticationProvider() throws Exception {
MyAuthenticationProvider authenticationProvider = new MyAuthenticationProvider(repository);
return authenticationProvider;
}
}
MyAuthenticationProvider类
package com.zhm.config;
import com.zhm.domain.UserInfo;
import com.zhm.repository.UserInfoRepository;
import com.zhm.utils.EncryptUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import java.util.HashSet;
import java.util.Set;
/**
* Created by zhm on 16-10-18.
*/
public class MyAuthenticationProvider implements AuthenticationProvider {
private UserInfoRepository userInfoRepository;
public MyAuthenticationProvider(UserInfoRepository userInfoRepository){
this.userInfoRepository = userInfoRepository;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
String username = String.valueOf(auth.getPrincipal());
String password = String.valueOf(auth.getCredentials());
UserInfo user = userInfoRepository.findByUsername(username);
// 2. Check the passwords match.
if (!user.getPassword().equalsIgnoreCase(EncryptUtils.encodeMD5String(password))) {
throw new BadCredentialsException("Bad Credentials");
}
// 3. Preferably clear the password in the user object before storing in authentication object
user.setPassword("");
// 4. Return an authenticated token, containing user data and authorities
return new UsernamePasswordAuthenticationToken(user.getUsername(), null, getAuthorities(user));
}
private Set<GrantedAuthority> getAuthorities(UserInfo user){
//可以添加用户权限
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
return authorities;
}
@Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}
重启应用,访问http://localhost:8080/user 输入zhm/123456就能访问接口了。
##完整实例 https://github.com/zhmlvft/user-rest