1、加入所需要的依赖

<!-- SpringSecurity 对 Web 应用进行权限管理 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.2.10.RELEASE</version>
        </dependency>
        <!-- SpringSecurity 配置 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.2.10.RELEASE</version>
        </dependency> <!-- SpringSecurity 标签库 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>4.2.10.RELEASE</version>
        </dependency>
    </dependencies>

2、在xml中加入 SpringSecurity 控制权限的 Filter

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3.在资源文件里加入springSecurity提供加密所需要的资源

<!-- 配置 BCryptPasswordEncoder 的 bean -->
	<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

4、创建配置类

// 表示当前类是一个配置类
@Configuration

// 启用Web环境下权限控制功能
@EnableWebSecurity

// 启用全局方法权限控制功能,并且设置prePostEnabled = true。保证@PreAuthority、@PostAuthority、@PreFilter、@PostFilter生效
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UserDetailsService userDetailsService;

	
	@Autowired
	private BCryptPasswordEncoder passwordEncoder;
	
	@Override
	protected void configure(AuthenticationManagerBuilder builder) throws Exception {
		
		// 临时使用内存版登录的模式测试代码
		// builder.inMemoryAuthentication().withUser("tom").password("123123").roles("ADMIN");
		
		// 正式功能中使用基于数据库的认证
		builder
			.userDetailsService(userDetailsService)
			.passwordEncoder(passwordEncoder);//加密
		
	}
	
	@Override
	protected void configure(HttpSecurity security) throws Exception {
		
		security
			.authorizeRequests()	// 对请求进行授权
			.antMatchers("/admin/to/login/page.html")	// 针对登录页进行设置
			.permitAll()			// 无条件访问
			.antMatchers("/bootstrap/**")	// 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/crowd/**")       // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/css/**")         // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/fonts/**")       // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/img/**")         // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/jquery/**")      // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/layer/**")       // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/script/**")      // 针对静态资源进行设置,无条件访问
			.permitAll()                    // 针对静态资源进行设置,无条件访问
			.antMatchers("/ztree/**")       // 针对静态资源进行设置,无条件访问
			.permitAll()
			.antMatchers("/admin/get/page.html")	// 针对分页显示Admin数据设定访问控制
			// .hasRole("经理")					// 要求具备经理角色
			.access("hasRole('经理') OR hasAuthority('user:get')")	// 要求具备“经理”角色和“user:get”权限二者之一
			.anyRequest()					// 其他任意请求
			.authenticated()				// 认证后访问
			.and()
			.exceptionHandling()
			.accessDeniedHandler(new AccessDeniedHandler() {
				
				@Override
				public void handle(HttpServletRequest request, HttpServletResponse response,
						AccessDeniedException accessDeniedException) throws IOException, ServletException {
					request.setAttribute("exception", new Exception("你没有权限访问"));
					request.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(request, response);
				}
			})
			.and()
			.csrf()							// 防跨站请求伪造功能
			.disable()						// 禁用
			.formLogin()					// 开启表单登录的功能
			.loginPage("/admin/to/login/page.html")	// 指定登录页面
			.loginProcessingUrl("/security/do/login.html")	// 指定处理登录请求的地址
			.defaultSuccessUrl("/admin/to/main/page.html")	// 指定登录成功后前往的地址
			.usernameParameter("loginAcct")	// 账号的请求参数名称
			.passwordParameter("userPswd")	// 密码的请求参数名称
			.and()
			.logout()						// 开启退出登录功能
			.logoutUrl("/seucrity/do/logout.html")			// 指定退出登录地址
			.logoutSuccessUrl("/admin/to/login/page.html")	// 指定退出成功以后前往的地址
			;
		
	}

}

5、使用自定义 UserDetailsService 完成登录

@Component
public class MyUserDetailsService implements UserDetailsService {
	
 @Autowired
    private AdminService adminService;

	// 总目标:根据表单提交的用户名查询User对象,并装配角色、权限等信息
	@Override
	public UserDetails loadUserByUsername(
			
			// 表单提交的用户名
			String username
			
		) throws UsernameNotFoundException {
		
		
		
		Admin admin = adminService.selectByName(username);
		
		// 2.给Admin设置角色权限信息
		List<GrantedAuthority> authorities = new ArrayList<>();
        //角色名字,开发中是在数据库里查询得到,只是为了练习这里的名字和权限是自己写的,不是从数据库查的
		
		authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
       //具有的权限
		authorities.add(new SimpleGrantedAuthority("UPDATE"));
		
		// 3.把admin对象和authorities封装到UserDetails中
		
		String userpswd = admin.getUserpswd();
		
		return new User(username, userpswd, authorities);
	}

}

6、常用注解

//角色为部长才可以查看分页
@PreAuthorize("hasRole('部长')")
	// @ResponseBody
	@RequestMapping("/role/get/page/info.json")
	public ResultEntity<PageInfo<Role>> getPageInfo(){}


//用户具有save权限才有使用保存用户的权限
@PreAuthorize("hasAuthority('user:save')")
    @RequestMapping("/admin/save.html")
    public String add(Admin admin) {