我有一個設計問題,我不知道如何解決。我使用Spring 3.2.4和Spring安全性3.1.4。達到用戶ID而不通過每個控制器
我在我的數據庫中的客戶表看起來像這樣:
create table Account (id identity,
username varchar unique,
password varchar not null,
firstName varchar not null,
lastName varchar not null,
university varchar not null,
primary key (id));
直到最近,我的用戶名是僅僅只有一個用戶名,但我改變了它是不是因爲許多用戶想登錄的電子郵件地址相反。
我有一個頭,我包括我的所有頁面,其有一個鏈接,用戶配置文件是這樣的:
<a href="/project/users/<%= request.getUserPrincipal().getName()%>" class="navbar-link"><strong><%= request.getUserPrincipal().getName()%></strong></a>
的問題是,現在<%= request.getUserPrincipal().getName()%>
返回的電子郵件,我不想鏈接用戶使用他們的電子郵件。相反,我想使用ID每個用戶都必須鏈接到配置文件。
如何從每個頁面訪問用戶標識?
我一直在想兩種解決方案,但我不知道:
- 變化主要包含了ID爲好,不知道如何做到這一點,有問題,找到就不錯了信息話題。
- 將模型屬性添加到包含整個用戶的所有控制器,但這樣會非常難看。
Account account = entityManager.find(Account.class, email);
model.addAttribute("account", account);
有更多方式的,以及和我不知道哪一個是喜歡。
我希望這已經夠清楚了,謝謝你的幫助。
======根據回答=======
我編輯的帳戶來實現的UserDetails編輯,現在看起來是這樣的(將修復後自動生成的東西):
@Entity
@Table(name="Account")
public class Account implements UserDetails {
@Id
private int id;
private String username;
private String password;
private String firstName;
private String lastName;
@ManyToOne
private University university;
public Account() {
}
public Account(String username, String password, String firstName, String lastName, University university) {
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.university = university;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public University getUniversity() {
return university;
}
public void setUniversity(University university) {
this.university = university;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
我也
添加<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
爲了我的jsp文件,並試圖達到ID
<sec:authentication property="principal.id" />
這使我根據以下
org.springframework.beans.NotReadablePropertyException: Invalid property 'principal.id' of bean class [org.springframework.security.authentication.UsernamePasswordAuthenticationToken]: Bean property 'principal.id' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
======編輯2我根據我對春天的社會樣本應用程序來回答=======
直到現在,我從來不需要改變任何東西。
這是我認爲是相關的文件,請告訴我,如果你需要看到除此之外的東西。
AccountRepository.java
public interface AccountRepository {
void createAccount(Account account) throws UsernameAlreadyInUseException;
Account findAccountByUsername(String username);
}
JdbcAccountRepository.java
@Repository
public class JdbcAccountRepository implements AccountRepository {
private final JdbcTemplate jdbcTemplate;
private final PasswordEncoder passwordEncoder;
@Inject
public JdbcAccountRepository(JdbcTemplate jdbcTemplate, PasswordEncoder passwordEncoder) {
this.jdbcTemplate = jdbcTemplate;
this.passwordEncoder = passwordEncoder;
}
@Transactional
public void createAccount(Account user) throws UsernameAlreadyInUseException {
try {
jdbcTemplate.update(
"insert into Account (firstName, lastName, username, university, password) values (?, ?, ?, ?, ?)",
user.getFirstName(), user.getLastName(), user.getUsername(), user.getUniversity(),
passwordEncoder.encode(user.getPassword()));
} catch (DuplicateKeyException e) {
throw new UsernameAlreadyInUseException(user.getUsername());
}
}
public Account findAccountByUsername(String username) {
return jdbcTemplate.queryForObject("select username, firstName, lastName, university from Account where username = ?",
new RowMapper<Account>() {
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Account(rs.getString("username"), null, rs.getString("firstName"), rs.getString("lastName"), new University("test"));
}
}, username);
}
}
的security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http pattern="/resources/**" security="none" />
<http pattern="/project/" security="none" />
<http use-expressions="true">
<!-- Authentication policy -->
<form-login login-page="/signin" login-processing-url="/signin/authenticate" authentication-failure-url="/signin?error=bad_credentials" />
<logout logout-url="/signout" delete-cookies="JSESSIONID" />
<intercept-url pattern="/addcourse" access="isAuthenticated()" />
<intercept-url pattern="/courses/**/**/edit" access="isAuthenticated()" />
<intercept-url pattern="https://stackoverflow.com/users/**/edit" access="isAuthenticated()" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder ref="passwordEncoder" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username, password, true from Account where username = ?"
authorities-by-username-query="select username, 'ROLE_USER' from Account where username = ?"/>
</authentication-provider>
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
這是我實現一個UserDetailsService
的嘗試210仍給我同樣的錯誤,我需要添加UserDetailsService的地方嗎? 與我最初的問題相比,這開始是別的,我可能會開始另一個問題。
對不起,我缺乏這方面的經驗。我必須閱讀。
unforunetly校長截至目前只有用戶名和其他一些重要的領域。我會研究你的其他建議 – nilsi