【问题标题】:In spring security 3,how to customize my @ PreAuthorize annotation?在spring security 3中,如何自定义我的@PreAuthorize注解?
【发布时间】:2013-01-11 05:47:55
【问题描述】:

这几天我遇到一个问题,我想不通,所以请帮助我...

我的实体:Utilisateur这是一个法语单词,意思是用户

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    public class Utilisateur implements Serializable 
    {
         private static final long serialVersionUID = 1L;
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         protected int id;
         protected String login;
         protected String password;
         protected String nom;
         protected String prenom;
         protected String email;
         protected String username;}

    @OneToOne(mappedBy="user", cascade={CascadeType.ALL})
    private Role role;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return login;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNom() {
        return nom;
    }

    public void setNom(String nom) {
        this.nom = nom;
    }

    public String getPrenom() {
        return prenom;
    }

    public void setPrenom(String prenom) {
        this.prenom = prenom;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }



    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

还有一个Role 实体。

在我的网络应用程序中,有一个控制器可以显示例如有关学生的信息(Etudiant 法语)

@EJB(mappedName = "Etudiant.EtudiantFacade")
    EtudiantFacade etudiantF;

    // Affiche le detail d'un Etudiant  (show the infomations of the student)
    @RequestMapping(value = "/Etudiant/{idEtudiant}/info")
    public ModelAndView detail(@PathVariable String idEtudiant, Model m) {
        m.addAttribute("etudiant",
                etudiantF.trouver(Integer.parseInt(idEtudiant)));
        return new ModelAndView("EtudiantInformation", "null", null);
    }

我直接使用实体Utilisateur 实现了我自己的CustomUseDetailService

 @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {
        // TODO Auto-generated method stub
        System.out.println("!!!!!!!!!!!!!!!!!");
        System.out.println(username);

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

            Utilisateur etudiant = etudiantF.trouverParLogin(username);


            return new User(etudiant.getLogin(), etudiant.getPassword(), enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,getAuthorities(etudiant.getRole().getRole()));

    }

我的 security.xml 如下:

<http auto-config="true" use-expressions="true">
        <intercept-url pattern="/app/Login" access="permitAll"/>
        <intercept-url pattern="/app/*" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"/>
        <form-login login-page="/app/Login" 
            authentication-success-handler-ref="authenticationSuccessHandler"/> 
        <logout logout-url="/app/Logout" logout-success-url="/"/>
    </http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="customUserDetailsService"/>
    </authentication-manager>

最后我的问题是: 对于一个学生,他的id是1,他的用户名是stu1,控制这个id为1的学生只能访问他自己的页面信息/ProjetName/Student/{studentId}/Info 我如何用@PreAuthorize编写代码,我在spring中看到了文档,有@PreAuthorize(#contract.name = principal.username)之类的例子,因为原则上有一个属性username,但是这里我需要的是Id,我使用@987654333 @ 匹配学生而不是用户名。那么我该如何解决呢?非常感谢...我找不到教程。

【问题讨论】:

    标签: annotations spring-security pre-authentication


    【解决方案1】:

    您可以为 User 类提供自己的实现(只需扩展 org.springframework.security.core.userdetails.User)。向其添加标识符字段。然后在 loadUserByUsername 方法中设置相应的值:

    @Override
    public UserDetails loadUserByUsername(String username)
        ...
        return new CustomUser(etudiant.getId(), etudiant.getLogin(), etudiant.getPassword(), enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,getAuthorities(etudiant.getRole().getRole()));
    
    }
    

    然后你就可以使用它了:

    @PreAuthorize(#contract.name = principal.id)
    

    【讨论】:

    • 感谢您的回复,该解决方案有效,但在我的情况下,我们使用 EJB 实体,所以如果我的实体 Utilisateur 也用户扩展类 UseDetail。不利于代码的复用吗?我不确定。那么在实际项目中,如果我们使用Entityclass如何解决这个问题。非常感谢
    • 我不明白你的问题。你能提供更多细节吗?
    • 在大多数教程中,我们都有一个用户类,如果我们想自定义我们自己的UserDetailService,我们可以让我们的User类扩展UserDetail。但我认为这只是一个简单的项目。在我的项目中,我的用户类是一个 POJO,它是一个 EJB 实体 bean。因此,如果我让我的用户类扩展 UserDetail,我知道它可以工作,但我不确定它是否也可重用。但这只是我的想法,我不知道它是否正确。我的项目有两个子项目,一个是ejb项目,另一个是引用ejb项目的web项目。
    • 如果你不想扩展 org.springframework.security.core.userdetails.User 类,那么你可以实现 org.springframework.security.core.userdetails.UserDetails
    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 2016-07-18
    • 2015-09-12
    • 2012-01-14
    • 1970-01-01
    • 2019-05-02
    • 2013-08-14
    • 1970-01-01
    相关资源
    最近更新 更多