原文参考:
http://wiki.jikexueyuan.com/project/spring-security/core-classes.html(组件介绍)
https://blog.csdn.net/code__code/article/details/53885510
https://blog.csdn.net/u012702547/article/details/54319508
在进行之前,首先要知道什么是 spring security 权限框架:
简介 ---- Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
优点 ----人们使用Spring Security有很多种原因,不过通常吸引他们的是在J2EE Servlet规范或EJB规范中找不到典型企业应用场景的解决方案。
特别要指出的是他们不能在WAR 或 EAR 级别进行移植。
这样,如果更换服务器环境,就要,在新的目标环境进行大量的工作,对应用系统进行重新配置安全。
使用Spring Security 解决了这些问题,也提供很多有用的,完全可以指定的其他安全特性。
可能知道,安全包括两个主要操作。
第一个被称为“认证”,是为用户建立一个他所声明的主体。主体一般是指用户,设备或可以在系统中执行动作的其他系统。
第二个叫“授权”,指的是一个用户能否在应用中执行某个操作,在到达授权判断之前,身份的主体已经由身份验证过程建立。
这些概念是通用的,不是Spring Security特有的。
在身份验证层面,Spring Security广泛支持各种身份验证模式,这些验证模型绝大多数都由第三方提供,或者正在开发的有关标准机构提供的,例如 Internet Engineering Task Force.
作为补充,Spring Security 也提供了自己的一套验证功能。
Spring Security 目前支持认证一体化如下认证技术:
HTTP BASIC authentication headers (一个基于IEFT RFC 的标准)
HTTP Digest authentication headers (一个基于IEFT RFC 的标准)
HTTP X.509 client certificate exchange (一个基于IEFT RFC 的标准)
LDAP (一个非常常见的跨平台认证需要做法,特别是在大环境)
Form-based authentication (提供简单用户接口的需求)
OpenID authentication
Computer Associates Siteminder
JA-SIG Central Authentication Service (CAS,这是一个流行的开源单点登录系统)
Transparent authentication context propagation for Remote Method Invocation and HttpInvoker (一个Spring远程调用协议)
进入正题
ssh可以参考:http://www.blogjava.net/SpartaYew/archive/2011/06/15/350630.html
springboot参考:
https://blog.csdn.net/u283056051/article/details/55803855
https://www.jianshu.com/p/e6655328b211
今天使用 spring boot 整合 spring security
使用环境:
项目中使用:
第一步:导入pom,只要加入security的pom,拦截就会生效
(这里只要有红色这个主要的就可以用)
第二步:配置核心文件WebSecurityConfig(java文件就可以,要加入@Configuration启动注解,并继承WebSecurityConfigurerAdapter)
package com.mozi.hip.empi.web.config;
import org.springframework.beans.factory.annotation.Autowired; 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.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration @EnableWebSecurity //@EnableGlobalMethodSecurity(prePostEnabled = true)//开启security注解 public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private UserDetailsService userDetailsService;
@Autowired LoginSuccessHandler loginSuccessHandler; @Autowired LoginFailureHandler loginFailureHandler;
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeRequests() //指定放开的路径,包括登录页面,样式路径,登录请求路径 .antMatchers("/login","/css/**","/images/**","/plugins/**","/scripts/**").permitAll() //其他地址的访问均需验证权限 .anyRequest().authenticated() .and() .formLogin() // 指定登陆页是login .loginPage("/login") .permitAll() .successHandler(loginSuccessHandler) .failureHandler(loginFailureHandler) .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login") .permitAll() .deleteCookies("remember-me") // 数据库中必须存在名为persistence_logins的表 //.invalidateHttpSession(false) .and() // 登陆以后记住用户,下次自动登陆 .rememberMe() // 两周有效 .tokenValiditySeconds(1209600); // 指定登陆信息所使用的数据源 // .tokenRepository(tokenRepository); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { //用户认证与密码认证 auth.userDetailsService(userDetailsService).passwordEncoder( new BCryptPasswordEncoder()); auth.eraseCredentials(false); } } |
上面我们用到了LoginSuccessHandler和LoginFailureHandler(自定义的)和粉色标注的自定义登录页面,这个页面要加入个启动类:
自定义跳转页面启动类MvcConfig:
package com.mozi.hip.empi.web.config;
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration public class MvcConfig extends WebMvcConfigurerAdapter{ @Override public void addViewControllers(ViewControllerRegistry registry){ registry.addViewController("/login").setViewName("login"); } } |
LoginSuccessHandler:
package com.mozi.hip.empi.web.config;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component;
import com.mozi.hip.core.domain.HipUser; import com.mozi.hip.empi.web.domain.CurrentUser;
@Component public class LoginSuccessHandler implements AuthenticationSuccessHandler{
@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { // 获取当前用户(domain接收) CurrentUser user = (CurrentUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); System.out.println(user.toString()); //转发到index页面 response.sendRedirect(request.getContextPath() +"/index"); }
} |
LoginFailureHandler:
package com.mozi.hip.empi.web.config;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.stereotype.Component;
@Component public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler{ public LoginFailureHandler() { this.setDefaultFailureUrl("/login"); } @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { /*保存登录日志*/ //saveLoginLog(request); super.onAuthenticationFailure(request, response, exception); } } |
第三步:(关键的部分)上面的是拦截部分,下面的是认证部分
如果想要上面websecurity的绿色认证部分起作用,我们还需要自定义一个类UserDetailServiceImpl(名字随意),这个类要实现UserDetailsService
package com.mozi.hip.empi.web.service.impl;
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set;
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.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component;
import com.mozi.hip.core.domain.HipRole; import com.mozi.hip.core.domain.HipUser; import com.mozi.hip.core.domain.HipUserRole; import com.mozi.hip.empi.web.domain.CurrentUser; import com.mozi.hip.empi.web.service.HipUserRoleService; import com.mozi.hip.empi.web.service.HipUserService;
@Component public class UserDetailServiceImpl implements UserDetailsService {
@Autowired private HipUserService hipUserService; @Autowired private HipUserRoleService hipUserRoleService;
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 根据用户名查询对象 HipUser user = hipUserService.findLoginName(username); if (user == null) { throw new UsernameNotFoundException("没有找到用户,用户登录名: " + username); } else { List List return (UserDetails) new CurrentUser(user, authorities); } }
private List Set for (int i = 0; i < userRoles.size(); i++) { auths.add(new SimpleGrantedAuthority(userRoles.get(i).getUserRoleId().toString())); } List return result; }
} |
这里绿色部分需要加入俩个东西:CurrentUser 和 CurrentUserControllerAdvice
CurrentUserControllerAdvice:
package com.mozi.hip.empi.web.controller.advice;
import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ModelAttribute;
import com.mozi.hip.empi.web.domain.CurrentUser;
/** * * @Title: CurrentUserControllerAdvice.java * @Package: com.hokai.hiip.web.controller.advice * @Description: session中用户信息 * @author Zhaoyan * @date 2016年9月27日 */ @ControllerAdvice public class CurrentUserControllerAdvice {
@ModelAttribute("currentUser") public CurrentUser getCurrentUser(Authentication authentication) { return (authentication == null) ? null : (CurrentUser) authentication .getPrincipal(); } } |
CurrentUser :
package com.mozi.hip.empi.web.domain;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import com.mozi.hip.core.domain.HipUser;
/** * 当前用户返回到界面信息 * @author tianyp * 2017年11月24日 下午4:05:30 * @see org.springframework.security.core.GrantedAuthority * @version 1.0 */ public class CurrentUser extends org.springframework.security.core.userdetails.User {
private static final long serialVersionUID = 1L;
private HipUser hipuser;
public CurrentUser(HipUser hipuser, List super(hipuser.getLoginName(), hipuser.getPwd(), authorities); this.hipuser = hipuser; }
public HipUser getUser() { return hipuser; }
public Integer getId() { return hipuser.getUserId(); }
public boolean isEnabled() { return Boolean.parseBoolean(String.valueOf(hipuser.getEnableFlag())) == false; } public boolean isAccountNonLocked() { return Boolean.parseBoolean(hipuser.getLockedFlag()) == false; } public boolean isAccountNonExpired() { return Boolean.parseBoolean(hipuser.getExpiredFlag()) == false; } /* * public Role getRole() { return user.getRole(); } */ @Override public String toString() { return "CurrentUser{" + "user=" + hipuser + "} " + super.toString(); } } |
以上,关键部分均已完成,所做是根据用户角色控制
整个部分实现与controller和页面基本无关,无页面和控制层也可以实现,这里注意误区