Пример формы входа в Spring
Я попытался выполнить поиск в Google, но не смог найти хороших примеров, когда имя пользователя и пароль проверяются в базе данных для целей аутентификации.
Другими словами, как я могу создать простую форму входа в систему, используя Spring и Hibernate, где учетные данные проверяются с помощью базы данных.
Обновить
Кто-нибудь может придумать простой пример, где я могу видеть, как идет поток и как входные данные передаются в спящий режим?
6 ответов
Сначала вы должны определить этот файл WEB-INF/spring/serurity-context.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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<http auto-config="true" />
<beans:bean id="myUserService" class="org.my.UserService" />
<authentication-provider user-service-ref="myUserService" />
</beans:beans>
Теперь вы должны создать org.my.UserService
класс и реализовать интерфейс org.springframework.security.core.userdetails.UserDetailsService
, Этот интерфейс имеет один метод:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, org.springframework.dao.DataAccessException
И в этом методе вы можете использовать Hibernate для загрузки пользователя по userName. Если пользователь не существует - просто сгенерируйте исключение UsernameNotFoundException, в противном случае верните новый инициализированный экземпляр UserDetails (там вы можете предоставить множество таких вещей, как роли пользователя, срок действия учетной записи и т. Д.).
Теперь приходит web.xml
:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>My Webapp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*-context.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Если у вас есть какие-либо вопросы или что-то идет не так, не стесняйтесь спрашивать:)
PS: Таким образом, с UserDetailsService вам не нужно проверять пароль на то, активна ли учетная запись пользователя и т. Д. Вы просто предоставляете информацию о безопасности Spring для пользователя с userName
и фреймворк проверяет самого пользователя. Например, если вы кодируете свои пароли с помощью MD5, вы можете использовать password-encoder
как это:
<beans:bean id="myUserService" class="org.my.UserService" />
<authentication-provider user-service-ref="myUserService">
<password-encoder hash="md5"/>
</authentication-provider>
Обновить
Теперь мы углубимся в UserService
- мой (упрощенный) пример из реального мира.
UserService
учебный класс:
import org.my_company.my_app.domain.User
public class UserService implements UserDetailsService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
// load user
User user = userDao.getUser(username);
if (user != null) {
// convert roles
List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
for (Privilege p : user.getPrivileges()) {
roles.add(new GrantedAuthorityImpl(p.getName()));
}
// initialize user
SecurityUser securityUser = new SecurityUser(
user.getUsername(),
user.getLdapAuth() ? getLdapPassword(user.getUsername()) : user.getPassword(),
user.getStatus() != User.Status.NOT_COMMITED, user.getStatus() != User.Status.BLOCKED, true, true,
roles.toArray(new GrantedAuthority[0])
);
securityUser.setUser(user);
return securityUser;
} else {
throw new UsernameNotFoundException("No user with username '" + username + "' found!");
}
}
}
Сейчас SecurityUser
:
import org.my_company.my_app.domain.User
public class SecurityUser extends org.springframework.security.core.userdetails.User {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public SecurityUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, GrantedAuthority[] authorities) throws IllegalArgumentException {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
И наконец UserDao
:
import org.my_company.my_app.domain.User
public class UserDao extends HibernateDaoSupport {
public User getUser(String username) {
List users = getHibernateTemplate().find("from User where username = ?", username);
return users == null || users.size() <= 0 ? null : (User) users.get(0);
}
}
Как вы можете видеть, я использовал HibernateTemplate
Вот.
Вы можете перейти к примеру формы входа в Spring здесь: http://www.roseindia.net/spring/spring-mvc-login-example.shtml.
Базовую xml-конфигурацию вы можете увидеть в посте "Легкий угол". Часть, которую он упомянул как "myUserService", - это bean-компонент, который реализует "UserDetailService". У него есть только один метод для реализации, а именно:
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException
Если вы используете Spring, то, вероятно, у вас будет Бин, который управляет доступом к вашей Таблице пользователей. Тот, который вы можете просто внедрить в этот класс для получения сведений о пользователе, например:
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException {
UserTable user = userbean.getUserbyName(name);
if (user == null) {
throw new UsernameNotFoundException("User " + name + " not found!");
}
Collection<GrantedAuthority> auth = getAuthorities(user.getAuthorities());
return new User(user.getName(), user.getPassword(), true, true, true, true, auth);
}
Теперь в bean-компоненте аутентификации все, что вам нужно, это внедрить этот bean-компонент и запросить его для UserDetails. Там вы можете использовать его, чтобы проверить правильность учетных данных и, если это так, заполните SecurityContext необходимой информацией для входа в систему.
@Override
public Boolean authenticate(String username, String password) {
UserDetails userdetail = null;
try {
userdetail = myUserService.loadUserByUsername(username);
} catch (UsernameNotFoundException e) {
return false;
} catch (DataAccessException e) {
return false;
}
if (!myUserService.encodePassword(password).equals(userdetail.getPassword())) {
return false;
}
Authentication auth = new UsernamePasswordAuthenticationToken(userdetail.getUsername(), userdetail.getPassword(),
userdetail.getAuthorities());
SecurityContext sc = new SecurityContextImpl();
ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
attr.getRequest().getSession().setAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY, userdetail.getUsername());
sc.setAuthentication(auth);
SecurityContextHolder.setContext(sc);
return true;
}
Конечно, это упрощенная версия реальной. Есть еще много проверок, которые вы должны выполнить, прежде чем сказать, что пользователь аутентифицирован (например, SQLInjection)
App-fuse предоставит вам полный рабочий пример: http://appfuse.org/display/APF/AppFuse+QuickStart
Или, если у вас установлен maven, просто запустите:
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-light-spring-security-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=myproject
Это сгенерирует легкий проект appfuse с spring mvc, spring security и hibernate.
Если вы используете базу данных, к которой можно получить доступ с помощью JDBC, вам не нужно создавать собственный поставщик аутентификации. Поставщик аутентификации уже позволяет вам запрашивать базу данных напрямую. Это сократит необходимый код до 9 строк XML вместо множества классов.
Я ответил здесь с примерами кода: аутентификация базы данных Spring Security 3 с помощью Hibernate
Ниже ссылка точно даст вам то, что вы ищете. Существует страница входа, которая принимает идентификатор пользователя и пароль. Пароль хранится в виде простого текста, так как это всего лишь тестовый проект. Используемая база данных - MySQL. Вы можете проверить шаги, скачать код и файл войны по ссылке ниже. Дайте мне знать, если у вас возникли проблемы с запуском приложения. Надеюсь, поможет! http://badalchowdhary.wordpress.com/2012/02/26/spring-hibernate-integration/