springboot 2.0 集成 Spring Security进行安全控制

添加依赖

<!-- spring security 权限框架依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UserDetailsService userDetailsService;

	/**
	 * 授权请求(主要就是静态界面、下载一些静态文件)
	 */
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/assets/**");
	}

	/**
	 * 验证用户的信息、处理注销
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
        .authorizeRequests()
        	//spring boot监控放行
			.antMatchers("/manage/**").permitAll()
            .antMatchers("/").permitAll()
            // swagger-ui
			.antMatchers("/swagger-ui.html", "/webjars/springfox-swagger-ui/**", "/swagger-resources/**",
					"/v2/api-docs")
			.permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login.xhtml")
            .loginProcessingUrl("/login")
            .successForwardUrl("/index.xhtml")
            .permitAll()
            .and()
        .logout()
        .logoutUrl("/logout")
            .permitAll();
	}

	/**
	 * 全局的用户校验
	 */
	@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

	
}

看到代码中我使用的是UserDetailsService,这里具体谈一下UserDetailsService。之前我们采用了配置文件的方式从数据库中读取用户进行登录。虽然该方式的灵活性相较于静态账号密码的方式灵活了许多,但是将数据库的结构暴露在明显的位置上,绝对不是一个明智的做法。本文通过Java代码实现UserDetailsService接口来实现身份认证。

UserDetailsService在身份认证中的作用

	Spring Security中进行身份验证的是AuthenticationManager接口,ProviderManager是它的一个默认实现,但它并不用来处理身份认证,而是委托给配置好的AuthenticationProvider,每个AuthenticationProvider会轮流检查身份认证。检查后或者返回Authentication对象或者抛出异常。
	验证身份就是加载响应的UserDetails,看看是否和用户输入的账号、密码、权限等信息匹配。此步骤由实现AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService验证用户名、密码和授权)处理。包含 GrantedAuthority 的 UserDetails对象在构建 Authentication对象时填入数据。
	上图解释:

在这里插入图片描述
新建CustomUserService类实现UserDetailsService接口

@Service
public class CustomUserService implements UserDetailsService {

	@Autowired
	private UserService userService;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		User user = userService.getUserByUsername(username);
		if (user == null) {
			throw new UsernameNotFoundException("用户名不存在");
		}
		if (!user.getStatus()) {
			throw new UsernameNotFoundException("用户账号已被删除");
		}

		return new org.springframework.security.core.userdetails.User(username, user.getPassword(), true, true, true,
				true, getGrantedAuthorities(user));
	}

	private List<GrantedAuthority> getGrantedAuthorities(User user) {

		List<GrantedAuthority> authorities = new ArrayList<>();
		return authorities;
	}

}

UserService 添加一个接口实现方法查询数据库:

User getUserByUsername(@RequestParam(name = "username") String username);

上述代码完成,剩下的就是编写界面代码了login.html。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head th:include="include/head::head"></head>
<head> 		
<link th:href="@{/assets/pages/css/login.css}" rel="stylesheet" type="text/css" />
</head>
<body class=" login">
    <div class="logo">
    </div>
        <div class="content">
            <form class="login-form" th:action="@{/login}" method="post">
                <h3 class="form-title font-green">登&nbsp;录</h3>
                <div th:if="${param.error}" class="alert alert-danger ">
                    <button class="close" data-close="alert"></button>
                    <span >用户名或密码错误</span>
                </div>
                <div class="form-group">
                    <!--ie8, ie9 does not support html5 placeholder, so we just show field title for that-->
                    <label class="control-label visible-ie8 visible-ie9">用户名</label>
                    <input class="form-control form-control-solid placeholder-no-fix" type="text" autocomplete="off" placeholder="用户名" name="username" />
                </div>
                <div class="form-group">
                    <label class="control-label visible-ie8 visible-ie9">密码</label>
                    <input class="form-control form-control-solid placeholder-no-fix" type="password" autocomplete="off" placeholder="密码" name="password" />
                </div>
                <div class="form-actions">
                    <button type="submit" class="btn green uppercase">登 录</button>
                </div>
            </form>
        </div>
</body>
</html>

最后就是做成功界面了接口,与界面实现了。

@RestController
public class IndexController extends BaseController {

	@Autowired
	private UserService userService;

	@RequestMapping("index.xhtml")
	public ModelAndView index(HttpServletRequest request) {
		User user = userService.getUserByUsername(getPrincipal());
		setSesionAttribute(request, Constants.SESSION_USER, user);
		return new ModelAndView("index");

	}

	private String getPrincipal() {
		String userName = null;
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

		if (principal instanceof UserDetails) {
			userName = ((UserDetails) principal).getUsername();
		} else {
			userName = principal.toString();
		}
		return userName;
	}

}
发布了22 篇原创文章 · 获赞 13 · 访问量 5789

猜你喜欢

转载自blog.csdn.net/weixin_43839457/article/details/90168184