部分引自 www.javaboy.org
在 SecurityConfig 上添加注解
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("yzn").password("$2a$10$WuUO9k/3LfTGzMEAKxNtAenttd9ulTq7wTj17ojqbU44Q5rwN/mWu").roles("admin")
.and()
.withUser("test").password("$2a$10$WuUO9k/3LfTGzMEAKxNtAenttd9ulTq7wTj17ojqbU44Q5rwN/mWu").roles("user");
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasAnyRole("admin", "user")
.anyRequest().authenticated()
.and()
.formLogin()
// 登录处理接口
.loginProcessingUrl("/doLogin")
// 定义登录页面,未登录时,访问一个需要登录之后才能访问的接口,会自动跳转到该页面
.loginPage("/login")
//定义登录时,用户名的 key,默认为 username
.usernameParameter("uname")
//定义登录时,用户密码的 key,默认为 password
.passwordParameter("passwd")
//登录成功的处理器
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication authentication) throws IOException, ServletException {
res.setContentType("application/json;charset=utf-8");
PrintWriter out = res.getWriter();
Map<String,Object> map = new HashMap();
map.put("status", 200);
// authentication.getPrincipal() 可以把登录者信息取出来
map.put("msg", authentication.getPrincipal());
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException e) throws IOException, ServletException {
res.setContentType("application/json;charset=utf-8");
PrintWriter out = res.getWriter();
Map<String,Object> map = new HashMap();
map.put("status", 200);
map.put("msg", "failed");
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
}
})
//和表单登录相关的接口统统都直接通过
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse res, Authentication authentication) throws IOException, ServletException {
res.setContentType("application/json;charset=utf-8");
PrintWriter out = res.getWriter();
Map<String,Object> map = new HashMap();
map.put("status", 200);
map.put("msg", "注销登录成功");
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
}
})
.and()
.csrf().disable();
}
}
添加Service
package org.javaboy.security.service;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class MethodService {
@PreAuthorize("hasRole('admin')")
public String admin() {
return "hello admin";
}
@Secured("ROLE_user")
public String user() {
return "hello user";
}
@PreAuthorize("hasAnyRole('admin','user')")
public String hello() {
return "hello hello";
}
}
Controller
@RestController
public class HelloController {
@Autowired
MethodService methodService;
@GetMapping("/hello")
public String hello() {
return "hello";
}
@GetMapping("/admin/hello")
public String admin() {
return "hello admin";
}
@GetMapping("/user/hello")
public String user() {
return "hello user";
}
@GetMapping("/login")
public String login() {
return "please login!!!";
}
@GetMapping("/hello1")
public String hello1() {
return methodService.admin();
}
@GetMapping("/hello2")
public String hello2() {
return methodService.user();
}
@GetMapping("/hello3")
public String hello3() {
return methodService.hello();
}
}
测试hello1,hello2,hello3接口,发现方法已经保护起来了