J'ai essayé de chercher dans Google, mais je n'ai trouvé aucun bon exemple où un nom d'utilisateur et un mot de passe sont vérifiés avec une base de données à des fins d'authentification.
En d'autres termes simples, comment puis-je créer un formulaire de connexion simple en utilisant Spring et Hibernate où les informations d'identification sont vérifiées avec la base de données.
Mettre à jour
Quelqu'un peut-il imaginer un exemple simple où je peux voir comment se passe le flux et comment les données d'entrée sont passées en veille prolongée?
Au début, vous devriez définir ce fichier 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>
Vous devez maintenant créer la classe org.my.UserService
et implémenter l'interface org.springframework.security.core.userdetails.UserDetailsService
. Cette interface a une méthode:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, org.springframework.dao.DataAccessException
Et dans cette méthode, vous pouvez utiliser Hibernate afin de charger utilisateur par nom d'utilisateur. Si l'utilisateur n'existe pas - lancez simplement une exception UsernameNotFoundException, sinon renvoyez-nous une nouvelle instance UserDetails intialisée (vous pouvez y fournir beaucoup d'éléments tels que les rôles d'utilisateur, la date d'expiration du compte, etc.).
Vient maintenant 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>
Si vous avez des questions ou si quelque chose ne va pas, n'hésitez pas à demander :)
PS: Donc, avec UserDetailsService, vous n'avez pas besoin de vérifier le mot de passe pour savoir si le compte d'utilisateur est actif, etc. Vous fournissez simplement des informations de sécurité Spring sur l'utilisateur avec la variable userName
fournie et la validation de l'utilisateur. Si vous encodez vos mots de passe avec MD5 par exemple, vous pouvez utiliser password-encoder
comme ceci:
<beans:bean id="myUserService" class="org.my.UserService" />
<authentication-provider user-service-ref="myUserService">
<password-encoder hash="md5"/>
</authentication-provider>
Nous allons maintenant plonger plus profondément dans UserService
- mon exemple (simplifié) du monde réel.
UserService
class:
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!");
}
}
}
Maintenant 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);
}
}
Et enfin 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);
}
}
Comme vous pouvez le voir, j’ai utilisé HibernateTemplate
ici.
Vous pouvez aller à l'exemple de formulaire de connexion de printemps ici: http://www.roseindia.net/spring/spring-mvc-login-example.shtml .
La configuration XML de base que vous pouvez voir dans le post de "Easy Angle". La partie qu'il a mentionnée sous le nom "myUserService" est un bean qui implémente "UserDetailService" .__
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException
Si vous utilisez Spring, vous aurez probablement un bean, qui gère l'accès à votre table utilisateur. Celui-ci, vous pouvez simplement l'injecter dans cette classe pour récupérer les détails de l'utilisateur, comme:
@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);
}
Désormais, dans un bean d'authentification, tout ce dont vous avez besoin est d'injecter ce bean et de lui demander les détails de l'utilisateur. Là, vous pouvez l'utiliser pour vérifier si les informations d'identification sont correctes et, le cas échéant, renseignez le SecurityContext avec les informations nécessaires pour pouvoir vous connecter.
@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;
}
Bien sûr, c’est une version simplifiée de la version réelle. Il y a beaucoup plus de vérifications que vous devez effectuer avant de dire que l'utilisateur est authentifié (SQLInjection par exemple)
App-Fuse vous donnera un exemple de travail complet: http://appfuse.org/display/APF/AppFuse+QuickStart
Ou si vous avez installé maven, lancez simplement:
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-light-spring-security-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=myproject
Cela générera un projet de lumière appfuse avec mvc, sécurité et hibernation.
Si vous utilisez une base de données accessible avec JDBC, vous n'avez pas besoin de créer un fournisseur d'authentification personnalisé. Le fournisseur d'authentification vous permet déjà d'interroger directement la base de données. Cela réduira le code requis à 9 lignes de XML au lieu d'une multitude de classes.
J'ai répondu ici avec des exemples de code: Authentification de la base de données Spring Security 3 avec Hibernate
Le lien ci-dessous vous donnera précisément ce que vous recherchez. Il existe une page de connexion qui accepte l'ID utilisateur et le mot de passe. Le mot de passe est stocké en texte brut car il ne s'agit que d'un projet test. La base de données utilisée est MySQL. Vous pouvez consulter les étapes, télécharger le code et le fichier war à partir du lien ci-dessous. Faites-moi savoir si vous rencontrez des problèmes pour exécuter l'application. J'espère que ça aide! http://badalchowdhary.wordpress.com/2012/02/26/spring-hibernate-integration/