痛苦 痛苦 痛苦
1、首先是跨域问题,当你的项目如果是前后台分离的。那么就一定会有恶心的跨域问题。但是我一般都是用比较常规的办法实现跨域,就是在spring boot配置cors跨域。如果有需要的小伙伴可以看我另外一篇博客。回到正题:你如果在前后端分离的情况下使用security时,会报跨域错误!我?????我不是配置了跨域了嘛?干嘛还提示我跨域问题,我很苦恼,我怀疑是不是我的跨域方式太low了?于是我更改了无数次跨域方式,从后台到前台,从axios到jsonp,不行,最终,我发现还是spring security在装怪。
你需要在你的 MyWebSecurityConfig 文件里面的 ** void configure(HttpSecurity http)方法里面配置
对,没错就是这个东西。你需要配置这个cor()配置。不然你永远无法跨域!
2、然后是你写好了代码以后,欢天喜地的想要测试一下有没有错,你改啊改啊,把权限到登陆成功到登陆失败都写了好了之后结果发现???又不行?于是你去直接访问后端地址,唉**
这都可以??为什么啊,我这样都可以,前后端分离就不行?
就给你返回了一段html,又让你登陆?哈哈哈哈,我就是这样,痛苦到不行,在更改了两三天之后。突然,我朋友告诉我这两个请求的区别在于一个会发送session信息,而另一个不会。我懵了!原来如此,于是我发现在前后端分离的时候如果你发送正常请求的时候每次所携带的session不同!没错,就是因为这样,所以即使你登陆之后,你再次发送请求的时候还是不行,因为你第二次发送的请求的session里没有存你是否登陆的信息。原因明了了之后,就好办了。
在你vue项目的main.js里面导入axios,然后给他的axios.defaults.withCredentials配置变为true就行了,这个配置有兴趣的可以看一下,大概就是不让人自定义session之类的,所以你用的就是同一个session。现在再来访问一次!
这里我们请求的是http://localhost:8000/admin/hello,我们登陆的具有这个admin(系统管理员)的权限。所以可以返回一个hello admin的信息!
到这里基本的你就完成了。然后还是附上代码。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/user/**")
.access("hasAnyRole('ADMIN','USER')")
.antMatchers("/db/**")
.access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest()
.authenticated()
.and()
.formLogin()
//.loginPage("/login_page")
.successHandler(new AuthenticationSuccessHandler () {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication auth) throws IOException, ServletException {
// TODO Auto-generated method stub
Object pricipal = auth.getPrincipal();
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
response.setStatus(200);
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("msg", pricipal);
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.failureHandler(new AuthenticationFailureHandler () {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
// TODO Auto-generated method stub
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
response.setStatus(200);
Map<String, Object> map = new HashMap<>();
map.put("status", 401);
if (e instanceof LockedException) {
map.put("msg", "账户被锁定,登陆失败");
} else if (e instanceof BadCredentialsException) {
map.put("msg", "账户名或密码输入错误,登陆失败");
} else if (e instanceof DisabledException) {
map.put("msg", "账户被禁用,登陆失败");
} else if (e instanceof AccountExpiredException) {
map.put("msg", "账户已过期,登陆失败");
} else if (e instanceof CredentialsExpiredException) {
map.put("msg", "密码过期,登陆失败");
} else {
map.put("msg", "登陆失败");
}
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.csrf()
.disable()
.exceptionHandling()
.accessDeniedHandler(getAccessDeniedHandler());
}
//
import org.springframework.beans.factory.annotation.Autowired;
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.Service;
import xxp.entity.User;
import xxp.mapper.UserMapper;
@Service
public class UserService implements UserDetailsService{
@Autowired
private UserMapper usermapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
User user = usermapper.loadUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("账户不存在");
}
// 通过id查找角色
user.setRoles(usermapper.getUserRolesByUid(user.getId()));
return user;
}
}
/
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class User implements UserDetails {
private Integer id;
private String username;
private String password;
private Boolean enabled;
private Boolean locked;
private List<Role> roles;
public User() {}
public User(Integer id, String username, String password, Boolean enabled, Boolean locked, List<Role> roles) {
super();
this.id = id;
this.username = username;
this.password = password;
this.enabled = enabled;
this.locked = locked;
this.roles = roles;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Boolean getLocked() {
return locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
// 配置权限信息
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
for (Role role: roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return this.password;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return this.username;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return !locked;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return enabled;
}
}
public class Role {
private Integer id;
private String name;
private String nameZh;
public Role () {}
public Role(Integer id, String name, String nameZh) {
super();
this.id = id;
this.name = name;
this.nameZh = nameZh;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNameZh() {
return nameZh;
}
public void setNameZh(String nameZh) {
this.nameZh = nameZh;
}
}
///
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginContorller {
@RequestMapping("/hello")
public String hello() {
return "hello world";
}
@RequestMapping("/admin/hello")
public String helloAdmin() {
return "hello admin";
}
@RequestMapping("/user/hello")
public String helloUser() {
return "hello user";
}
@RequestMapping("/db/hello")
public String helloDb() {
return "hello db";
}
@RequestMapping("/login_page")
public String loginPage() {
return "error";
}
}
那这里就这样了吧!0.0