如何动态限制spring security中的路由? [英] How to restrict routes in spring security dynamically?
问题描述
美好的一天,
我使用 spring security 限制用户,我使用 mongodb.
I am using spring security to restrict user, and i am using mongodb.
我已经创建了 UserDetail 和 userDetail 服务.
I have created UserDetail and userDetail Services.
她是我的网络安全配置.
her is my webSecurity config.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService mongoUserDetails() {
return new CustomUserDetailsService();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(mongoUserDetails());
authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/static/unsecure/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
我像这样在数据库中存储权限.
I am storing permissions in database like this.
"permissions" : [
"/reports/report1",
"/reports/report2"
]
这里是 userDetail 服务.
and here is userDetail service.
public class MongoUserDetails implements UserDetails {
private final String username;
private final String password;
private final List<GrantedAuthority> grantedAuthorities;
private final boolean enabled;
public MongoUserDetails(String username, String password, String[] authorities, boolean isEnabled) {
this.username = username;
this.password = password;
this.grantedAuthorities = AuthorityUtils.createAuthorityList(authorities);
this.enabled = isEnabled;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
在私人最终列表中授予权限;我已成功存储权限.分别是/reports/report1"、/reports/report2"
in private final List grantedAuthorities; I have successfully stored authorites. which are "/reports/report1", "/reports/report2"
当我运行我的 Web 应用程序时,它将我重定向到登录页面,并在有效凭据后将我重定向到/hello 页面.
When i run my web application it is redirecting my to login page and after valid credentials it redirects my to /hello page.
现在我正在创建控制器和动作,例如
Now i am creating controllers and actions like
@Controller
@ResponseBody
public class MyController {
@GetMapping("/user/greeting")
public String greeting(HttpServletRequest request){
return "welcome secure";
}
@GetMapping("/login1")
public String greeting1(HttpServletRequest request){
}
}
所以既然列出了授予权限;不包含此路线,不应允许用户执行此操作
so since List grantedAuthorities; does not contains this route it should not allowed the user for this action
我怎样才能做到这一点.假设所有权限都是动态的.
how can i achieve this. assuming all authorities are dynamic.
谢谢.
推荐答案
我的例子:认证服务:
@Service
public class AuthService implements UserDetailsService {
@Autowired
private UserJpaRepository userJpaRepository;
@Autowired
private UserProfileJPARepository profileJPARepository;
@Autowired
private UserProfileContainer profileContainer;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = (User) userJpaRepository.findByLogin(username);
GrantedAuthority authority = new SimpleGrantedAuthority(user.getRole().name());
UserDetails userDetails = (UserDetails) new SecureUser(
user.getId(),
user.getFirstName(),
user.getLastName(),
user.getEmail(),
user.getMobileNumber(),
user.getLogin(),
user.getPassword(),
user.isActive(),
true,
true,
true,
Arrays.asList(authority)
);
user.setLastLogonTime(new Timestamp((new Date()).getTime()));
userJpaRepository.saveAndFlush(user);
profileContainer.setUser(user);
return userDetails;
}
}
会话范围的 bean:
Session scoped bean:
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserProfileContainer {
private User user = null;
public UserProfileContainer() {
}
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
在 User 类中,你可以存储一个 List
And in User class you cal store a List<String> allowedURLS = new ArrayList<>();
修改后:
我写了这个例子.在这种情况下,我有一些 SecureUser.class 扩展了 org.springframework.security.core.userdetails.User
并且在这个类中我有 Set
实际上是HashSet.这是自定义过滤器:
I've wrote this example. In this case I have some SecureUser.class which extends org.springframework.security.core.userdetails.User
and in this class I have Set<String> allowedPathSet
actually HashSet. And here is the custom filter:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// nothing here...
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession(true);
SecurityContextImpl sci = (SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT");
if (sci != null) {
SecureUser user = (SecureUser) sci.getAuthentication().getPrincipal();
String url = req.getRequestURI();
if (!user.path.contains("url")) ((HttpServletResponse) response).sendRedirect("http://redirect-URL-Here/");
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
这个例子不是灵丹妙药,但主要思想在这里出现并且它有效.
This example isn't a silver bullet but the main idea is present here and it work.
这篇关于如何动态限制spring security中的路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!