【发布时间】:2013-12-15 06:12:05
【问题描述】:
我是 Spring Security 的新手。我有两个用户角色,例如管理员和普通用户。我想访问一些只有管理员用户才能访问的jsp,但问题是一旦用户注销,他/她仍然可以访问我在spring security config中限制的jsp页面。
让我知道我在这里所做的是否正确?
谢谢
spring_security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true">
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/user/**" access="ROLE_USER" />
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
<beans:bean id="customUserDetailsService"
class="com.nikunj.javabrains.services.CustomUserDetailsService"></beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
</authentication-provider>
</authentication-manager>
//------------------ 控制器
package com.nikunj.javabrains.controller;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.nikunj.javabrains.domain.User;
import com.nikunj.javabrains.services.UserService;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String printWelcome(ModelMap model, Principal principal,
HttpServletRequest request) {
String name = principal.getName(); // get logged in username
model.addAttribute("username", name);
model.addAttribute("message",
"Spring Security login + database example");
if (request.isUserInRole("ROLE_ADMIN")) {
return "admin_page";
}
return "common_page";
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model) {
return "login";
}
@RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginerror(ModelMap model) {
model.addAttribute("error", "true");
return "login";
}
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model) {
return "login";
}
@RequestMapping("/regiPage")
public String regiPage(@ModelAttribute("user") User user,
BindingResult result) {
return "registration";
}
@RequestMapping(value = "/saveUser", method = RequestMethod.POST)
public String saveUserData(@ModelAttribute("user") User user,
BindingResult result) {
userService.addUser(user);
return "login";
}
}
</beans:beans>
//------------------------
自定义服务类
import com.nikunj.javabrains.dao.UserDao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.User;
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 org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserDao userDAO;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
com.nikunj.javabrains.domain.User domainUser = userDAO.getUser(username);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
System.out.println("*************************************");
System.out.println(domainUser.getId());
return new User(
domainUser.getUsername(),
domainUser.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(domainUser.getId())
);
}
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("ROLE_ADMIN");
} else {
roles.add("ROLE_USER");
}
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
//---------------------------
@Controller
public class AdminController {
@Autowired
private UserService userService;
@RequestMapping(value = "/admininput", method = RequestMethod.GET)
public String login(ModelMap model) {
System.out.println("*************************");
return "admininputpage";
}
}
【问题讨论】:
-
你如何测试这个?最初(甚至在登录之前)用户是否必须登录?当用户单击/选择注销时,您调用的是哪个 URL?
-
你如何测试用户仍然可以访问这些页面?
-
管理员登录后这个欢迎页面的 URL 是“localhost:8080/Test3/welcome”。管理员可以使用此 URL“localhost:8080/Test3/admininput”访问管理员限制页面,但是当管理员注销时,任何人都可以通过简单复制并在地址栏中粘贴此 URL 来访问此页面。
-
在同一个浏览器中?不同的浏览器?确保您实际上是在服务器上点击该页面,而不是缓存版本(浏览器缓存)正在服务器!。一般来说,您希望在受保护的页面上禁用缓存。
标签: java spring jakarta-ee spring-mvc spring-security