0

ここで何が間違っているのか理解できませんでした。ページ /user/test.jsp にアクセスしようとしていますが、エラー 403 アクセス拒否エラーが発生しています。

この問題は、UserEntity クラスの ManyToMany アノテーションに起因していると思います。できる限りのことを試しましたが、まだこれを解決できません。

さらに調査した結果、user_security_role が DB からロードされていないようです。

Assembler クラスの buildUserFromUserEntity のコードの次の部分が空の SecurityRoleCollection を返すため、これが事実であることはわかっています。

for (SecurityRoleEntity role : userEntity.getSecurityRoleCollection()) {
    authorities.add(new GrantedAuthorityImpl(role.getName()));
}

テーブルに使用した SQL は次のとおりです (チュートリアルから)。

CREATE TABLE IF NOT EXISTS security_role (

    `id` INT(11) NOT NULL AUTO_INCREMENT ,

    `name` VARCHAR(50) NULL DEFAULT NULL ,

    PRIMARY KEY (`id`) )

    ENGINE = InnoDB

    AUTO_INCREMENT = 4

    DEFAULT CHARACTER SET = latin1;


CREATE TABLE IF NOT EXISTS user (

    `id` INT(11) NOT NULL AUTO_INCREMENT ,

    `first_name` VARCHAR(45) NULL DEFAULT NULL ,

    `family_name` VARCHAR(45) NULL DEFAULT NULL ,

    `dob` DATE NULL DEFAULT NULL ,

    `password` VARCHAR(45) NOT NULL ,

    `username` VARCHAR(45) NOT NULL ,

    `confirm_password` VARCHAR(45) NOT NULL ,

    `active` TINYINT(1) NOT NULL ,

    PRIMARY KEY (`id`) ,

    UNIQUE INDEX `username` (`username` ASC) )

    ENGINE = InnoDB

    AUTO_INCREMENT = 9

    DEFAULT CHARACTER SET = latin1;


CREATE TABLE IF NOT EXISTS user_security_role (

    `user_id` INT(11) NOT NULL ,

    `security_role_id` INT(11) NOT NULL ,

    PRIMARY KEY (`user_id`, `security_role_id`) ,

    INDEX `security_role_id` (`security_role_id` ASC) ,

    CONSTRAINT `user_security_role_ibfk_1`

    FOREIGN KEY (`user_id` )

    REFERENCES `user` (`id` ),

    CONSTRAINT `user_security_role_ibfk_2`

    FOREIGN KEY (`security_role_id` )

    REFERENCES `security_role` (`id` ))

    ENGINE = InnoDB

    DEFAULT CHARACTER SET = latin1;

これは、私が作業できないトリッキーな部分です: プライベート Set securityRoleCollection; 用に構成された注釈。属性はDBからデータをロードしません。ここで何が間違っているのかわかりません。

public class UserEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "family_name")
    private String familyName;

    @Column(name = "dob")
    @Temporal(TemporalType.DATE)
    private Date dob;

    @Basic(optional = false)
    @Column(name = "password")
    private String password;

    @Basic(optional = false)
    @Column(name = "username")
    private String username;

    @Basic(optional = false)
    @Column(name = "confirm_password")
    private String confirmPassword;

    @Basic(optional = false)
    @Column(name = "active")
    private boolean active;

    @JoinTable(name = "user_security_role", joinColumns = {

    @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = {

    @JoinColumn(name = "security_role_id", referencedColumnName = "id") })
    @ManyToMany
    private Set<SecurityRoleEntity> securityRoleCollection;

    public UserEntity() {

    }

ここに私の UserEntityDAOImpl クラスがあります:

public class UserEntityDAOImpl implements UserEntityDAO {

    public UserEntity findByName(String username) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;
        UserEntity user = null;
        try {
            transaction = session.beginTransaction();
            user = (UserEntity)session.createQuery("select u from UserEntity u where u.username = '"
                    + username + "'").uniqueResult();

            transaction.commit();
        } catch (HibernateException e) {
            transaction.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return user;
    }

SecurityRoleEntity クラスは次のとおりです。

@Entity
@Table(name = "security_role", catalog = "userauth", schema = "")
@NamedQueries({

        @NamedQuery(name = "SecurityRoleEntity.findAll", query = "SELECT s FROM SecurityRoleEntity s"),

        @NamedQuery(name = "SecurityRoleEntity.findById", query = "SELECT s FROM SecurityRoleEntity s WHERE s.id = :id"),

        @NamedQuery(name = "SecurityRoleEntity.findByName", query = "SELECT s FROM SecurityRoleEntity s WHERE s.name = :name") })
public class SecurityRoleEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @ManyToMany(mappedBy = "securityRoleCollection", fetch = FetchType.EAGER)
    private List<UserEntity> userCollection;

    public SecurityRoleEntity() {

    }

        getters and setters...

アセンブラクラスは次のとおりです。

@Service("assembler")
public class Assembler {

    @Transactional(readOnly = true)
    User buildUserFromUserEntity(UserEntity userEntity) {

        String username = userEntity.getUsername();
        String password = userEntity.getPassword();
        boolean enabled = userEntity.getActive();
        boolean accountNonExpired = userEntity.getActive();
        boolean credentialsNonExpired = userEntity.getActive();
        boolean accountNonLocked = userEntity.getActive();

        Collection<GrantedAuthorityImpl> authorities = new ArrayList<GrantedAuthorityImpl>();

        for (SecurityRoleEntity role : userEntity.getSecurityRoleCollection()) {
            authorities.add(new GrantedAuthorityImpl(role.getName()));
        }

        User user = new User(username, password, enabled,
        accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);

        return user;

    }

}

これが私のspring-security.xmlの内容です:

<beans:bean id="userDetailsService" class="service.UserDetailsServiceImpl">
</beans:bean>

<beans:bean id="assembler" class="service.Assembler">
</beans:bean>

<!-- <context:component-scan base-package="org.intan.pedigree" /> -->

<http auto-config='true'>
    <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
    <intercept-url pattern="/user/**" access="ROLE_User" />
    <!-- <security:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" 
        /> -->
</http>

<beans:bean id="daoAuthenticationProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>

<beans:bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
    <beans:property name="providers">
        <beans:list>
            <beans:ref local="daoAuthenticationProvider" />
        </beans:list>
    </beans:property>
</beans:bean>

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="plaintext" />
    </authentication-provider>
</authentication-manager>

UserDetailsS​​erviceImpl は次のとおりです。

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserEntityDAO dao;

    @Autowired
    private Assembler assembler;

    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username)

    throws UsernameNotFoundException, DataAccessException {

        UserDetails userDetails = null;

        UserEntity userEntity = dao.findByName(username);

        if (userEntity == null)

            throw new UsernameNotFoundException("user not found");

        return assembler.buildUserFromUserEntity(userEntity);

    }

}

アクセスしようとしているページのコントローラーは次のとおりです。

public class HowDoesItWorkController implements Controller {

protected final Log logger = LogFactory.getLog(getClass());

@PreAuthorize("hasRole('ROLE_User')")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    logger.info("returning contact view");
    return new ModelAndView("/explain");
}

}

私はこのチュートリアルに従っています: http://giannisapi.wordpress.com/2011/09/21/spring-3-spring-security-implementing-custom-userdetails-with-hibernate/

これらのロールを挿入すると言います:

insert into security_role(name) values ("ROLE_admin");

insert into security_role(name) values ("ROLE_User");

DBに挿入されるロールの名前はconfigファイルで設定されたものと同じでなければならないと思ったので、xmlファイルの名前をDBの名前に合わせて変更しましたが、何も変わりません。

DB 内の他のすべてのデータは良好なようです。

アクセスしようとしているページが /user にあることも確認しました。

4

2 に答える 2

0

私は問題を解決することができました。これは私の間違いでした。hibernate.cfg.xml ファイルの下で適切なデータベースを使用していませんでした。

ここで構成されたデータベースは、3 つのテーブルもある別のデータベースを参照していましたが、それらが空だったため、休止要求によってロールが選択されませんでした。

于 2012-07-19T04:11:52.300 に答える
0

UserEntityDAO を呼び出したときに、UserEntity の securityRoleCollection がフェッチされていません。findByName()。結合フェッチ クエリを実行するように DAO を実装する必要があります (おそらくより効率的です)。

@ManyToMany(fetch = FetchType.EAGER)
private Set<SecurityRoleEntity> securityRoleCollection

それがあなただけの問題ではないと思います。すべてのロール名が同じであることを確認する必要があります-上記のコードには現在次のものがあります。

ROLE_REGISTERED_USER
ROLE_User

それらは同じである必要があります (SecurityRoleEntity クラスが 2 つの間でマッピングされていない場合は?)

于 2012-07-18T02:14:06.370 に答える