【问题标题】:Spring security user role and access jspSpring安全用户角色和访问jsp
【发布时间】: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 用于注销并登录。
  • 你如何测试用户仍然可以访问这些页面?
  • 管理员登录后这个欢迎页面的 URL 是“localhost:8080/Test3/welcome”。管理员可以使用此 URL“localhost:8080/Test3/admininput”访问管理员限制页面,但是当管理员注销时,任何人都可以通过简单复制并在地址栏中粘贴此 URL 来访问此页面。
  • 在同一个浏览器中?不同的浏览器?确保您实际上是在服务器上点击该页面,而不是缓存版本(浏览器缓存)正在服务器!。一般来说,您希望在受保护的页面上禁用缓存。

标签: java spring jakarta-ee spring-mvc spring-security


【解决方案1】:

好的,根据您的最后评论,URL /admininput 正在被所有人访问。

这是我所期望的行为,因为没有为此 URL 模式定义安全规则。

在您的安全配置中,您定义以下规则:

<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/user/**" access="ROLE_USER" />

此配置将要求所有具有 URL 模式 /admin/** 的资源都使用角色 ROLE_ADMIN 登录,并且所有具有 URL 模式 /user/** 的资源都使用角色 ROLE_USER 登录。所有其他 URL 模式都是 permitAll。

如果您想限制该 URL,您需要更改 URL 模式或添加拦截规则。例如

将 URL 从 /admininput 更改为 /admin/input/admin/admininput

或者,添加显式拦截规则(或其他基于模式的规则)以覆盖此 URL:

<intercept-url pattern="/admininput" access="ROLE_ADMIN" />

(虽然,为每个 URL 设置明确的拦截器规则并不是一个好主意!所以如果可能的话,最好将 URL 更改为您已经定义的约定)

【讨论】:

  • pattern="/admin*"?
【解决方案2】:

您可以在 url 中使用唯一的会话 id。如果在注销后或通过复制 url 销毁会话,则如果没有登录 URL 并记录会话,则无法访问 URL。

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 2012-04-08
    • 2011-05-30
    • 2016-03-14
    • 2015-10-28
    相关资源
    最近更新 更多