mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-05 04:38:10 +08:00
Store remember me on server side #PL-3787
This commit is contained in:
parent
e70920dac7
commit
968d8eecc7
@ -743,6 +743,21 @@ create table SYS_JMX_INSTANCE (
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID varchar(36) not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID varchar(36) not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create function NEWID() returns varchar(36)
|
||||
return uuid(uuid());
|
||||
|
||||
|
@ -809,6 +809,23 @@ create index IDX_SYS_QUERY_RESULT_SESSION_KEY on SYS_QUERY_RESULT (SESSION_ID, Q
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID uniqueidentifier not null,
|
||||
CREATE_TS datetime,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID uniqueidentifier not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
insert into SEC_GROUP (ID, CREATE_TS, VERSION, NAME, PARENT_ID)
|
||||
values ('0fa2b1a5-1d68-4d69-9fbd-dff348347f93', current_timestamp, 0, 'Company', null)^
|
||||
|
||||
|
@ -579,6 +579,20 @@ create table SEC_USER_SUBSTITUTION (
|
||||
)^
|
||||
create index IDX_SEC_USER_SUBSTITUTION_USER on SEC_USER_SUBSTITUTION(USER_ID)^
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID varchar2(32) not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar2(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID varchar2(32) not null,
|
||||
TOKEN varchar2(32) not null,
|
||||
--
|
||||
primary key (ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
||||
|
||||
alter table SYS_APP_FOLDER add constraint FK_SYS_APP_FOLDER_FOLDER foreign key (FOLDER_ID) references SYS_FOLDER(ID)^
|
||||
|
||||
alter table SYS_ATTR_VALUE add constraint SYS_ATTR_VALUE_CATEGORY_ATT_ID foreign key (CATEGORY_ATTR_ID) references SYS_CATEGORY_ATTR(ID)^
|
||||
@ -635,6 +649,8 @@ alter table SEC_USER_SETTING add constraint SEC_USER_SETTING_USER foreign key (U
|
||||
alter table SEC_USER_SUBSTITUTION add constraint FK_SEC_USER_SUB_SUB_USE foreign key (SUBSTITUTED_USER_ID) references SEC_USER(ID)^
|
||||
alter table SEC_USER_SUBSTITUTION add constraint FK_SEC_USER_SUBSTITUTION_USER foreign key (USER_ID) references SEC_USER(ID)^
|
||||
|
||||
alter table SEC_REMEMBER_ME add constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)^
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create or replace function NEWID return varchar2
|
||||
|
@ -776,6 +776,24 @@ create index IDX_SYS_QUERY_RESULT_ENTITY_SESSION_KEY on SYS_QUERY_RESULT (ENTITY
|
||||
create index IDX_SYS_QUERY_RESULT_SESSION_KEY on SYS_QUERY_RESULT (SESSION_ID, QUERY_KEY)^
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID uuid not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID uuid not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
create or replace function newid()
|
||||
returns uuid
|
||||
as '$libdir/uuid-ossp', 'uuid_generate_v1'
|
||||
|
15
modules/core/db/update/hsql/14/140708-addRememberMeTable.sql
Normal file
15
modules/core/db/update/hsql/14/140708-addRememberMeTable.sql
Normal file
@ -0,0 +1,15 @@
|
||||
-- $Id$
|
||||
-- Description: add table for server-side remember me
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID varchar(36) not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID varchar(36) not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
@ -0,0 +1,17 @@
|
||||
-- $Id$
|
||||
-- Description: add table for server-side remember me
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID uniqueidentifier not null,
|
||||
CREATE_TS datetime,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID uniqueidentifier not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
@ -0,0 +1,18 @@
|
||||
-- $Id$
|
||||
-- Description: add table for server-side remember me
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID varchar2(32) not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar2(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID varchar2(32) not null,
|
||||
TOKEN varchar2(32) not null,
|
||||
--
|
||||
primary key (ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
||||
|
||||
alter table SEC_REMEMBER_ME add constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)^
|
@ -0,0 +1,17 @@
|
||||
-- $Id$
|
||||
-- Description: add table for server-side remember me
|
||||
|
||||
create table SEC_REMEMBER_ME (
|
||||
ID uuid not null,
|
||||
CREATE_TS timestamp,
|
||||
CREATED_BY varchar(50),
|
||||
VERSION integer,
|
||||
--
|
||||
USER_ID uuid not null,
|
||||
TOKEN varchar(32) not null,
|
||||
--
|
||||
primary key (ID),
|
||||
constraint FK_SEC_REMEMBER_ME_USER foreign key (USER_ID) references SEC_USER(ID)
|
||||
)^
|
||||
create index IDX_SEC_REMEMBER_ME_USER on SEC_REMEMBER_ME(USER_ID)^
|
||||
create index IDX_SEC_REMEMBER_ME_TOKEN on SEC_REMEMBER_ME(TOKEN)^
|
@ -83,6 +83,33 @@ public class LoginServiceBean implements LoginService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
try {
|
||||
return loginWorker.loginByRememberMe(login, rememberMeToken, locale);
|
||||
} catch (LoginException e) {
|
||||
log.info("Login failed: " + e.toString());
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
log.error("Login error", e);
|
||||
throw wrapInLoginException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale, Map<String, Object> params)
|
||||
throws LoginException {
|
||||
try {
|
||||
return loginWorker.loginByRememberMe(login, rememberMeToken, locale, params);
|
||||
} catch (LoginException e) {
|
||||
log.info("Login failed: " + e.toString());
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
log.error("Login error", e);
|
||||
throw wrapInLoginException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
try {
|
||||
@ -103,6 +130,11 @@ public class LoginServiceBean implements LoginService {
|
||||
return loginWorker.getSession(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
return loginWorker.checkRememberMe(login, rememberMeToken);
|
||||
}
|
||||
|
||||
protected LoginException wrapInLoginException(Throwable throwable) {
|
||||
//noinspection ThrowableResultOfMethodCallIgnored
|
||||
Throwable rootCause = ExceptionUtils.getRootCause(throwable);
|
||||
@ -111,4 +143,4 @@ public class LoginServiceBean implements LoginService {
|
||||
// send text only to avoid ClassNotFoundException when the client has no dependency to some library
|
||||
return new LoginException(rootCause.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,19 @@ public interface LoginWorker {
|
||||
/**
|
||||
* @see LoginService#loginTrusted(String, String, java.util.Locale, java.util.Map))
|
||||
*/
|
||||
UserSession loginTrusted(String login, String password, Locale locale, Map<String, Object> params) throws LoginException;
|
||||
UserSession loginTrusted(String login, String password, Locale locale, Map<String, Object> params)
|
||||
throws LoginException;
|
||||
|
||||
/**
|
||||
* @see LoginService#loginByRememberMe(String, String, java.util.Locale))
|
||||
*/
|
||||
UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* @see LoginService#loginTrusted(String, String, java.util.Locale, java.util.Map))
|
||||
*/
|
||||
UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale, Map<String, Object> params)
|
||||
throws LoginException;
|
||||
|
||||
/**
|
||||
* @see LoginService#logout()
|
||||
@ -67,4 +79,9 @@ public interface LoginWorker {
|
||||
* @throws LoginException in case of unsuccessful log in
|
||||
*/
|
||||
UserSession loginSystem(String login) throws LoginException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.haulmont.cuba.security.app.LoginService#checkRememberMe(String, String)
|
||||
*/
|
||||
boolean checkRememberMe(String login, String rememberMeToken);
|
||||
}
|
@ -8,6 +8,7 @@ import com.haulmont.cuba.core.*;
|
||||
import com.haulmont.cuba.core.app.ServerConfig;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.core.sys.remoting.RemoteClientInfo;
|
||||
import com.haulmont.cuba.security.entity.RememberMeToken;
|
||||
import com.haulmont.cuba.security.entity.User;
|
||||
import com.haulmont.cuba.security.global.LoginException;
|
||||
import com.haulmont.cuba.security.global.NoUserSessionException;
|
||||
@ -30,9 +31,10 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* Class that encapsulates the middleware login/logout functionality.
|
||||
*
|
||||
* @see com.haulmont.cuba.security.app.LoginServiceBean
|
||||
*
|
||||
* @author krivopustov
|
||||
* @version $Id$
|
||||
* @see com.haulmont.cuba.security.app.LoginServiceBean
|
||||
*/
|
||||
@ManagedBean(LoginWorker.NAME)
|
||||
public class LoginWorkerBean implements LoginWorker {
|
||||
@ -81,11 +83,24 @@ public class LoginWorkerBean implements LoginWorker {
|
||||
log.warn("Failed to authenticate: " + login);
|
||||
return null;
|
||||
} else {
|
||||
//noinspection UnnecessaryLocalVariable
|
||||
User user = (User) list.get(0);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected RememberMeToken loadRememberMeToken(String rememberMeToken, User user) {
|
||||
EntityManager em = persistence.getEntityManager();
|
||||
TypedQuery<RememberMeToken> query = em.createQuery(
|
||||
"select rt from sec$RememberMeToken rt where rt.token = :token and rt.user.id = :userId",
|
||||
RememberMeToken.class);
|
||||
query.setParameter("token", rememberMeToken);
|
||||
query.setParameter("userId", user.getId());
|
||||
|
||||
return query.getFirstResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession login(String login, String password, Locale locale) throws LoginException {
|
||||
if (password == null)
|
||||
@ -204,6 +219,48 @@ public class LoginWorkerBean implements LoginWorker {
|
||||
return loginTrusted(login, password, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
Transaction tx = persistence.createTransaction();
|
||||
try {
|
||||
User user = loadUser(login);
|
||||
|
||||
if (user == null) {
|
||||
throw new LoginException(
|
||||
messages.formatMessage(getClass(), "LoginException.InvalidActiveDirectoryUser", locale, login));
|
||||
}
|
||||
|
||||
RememberMeToken loginToken = loadRememberMeToken(rememberMeToken, user);
|
||||
if (loginToken == null) {
|
||||
throw new LoginException(getInvalidCredentialsMessage(login, locale));
|
||||
}
|
||||
|
||||
Locale userLocale = locale;
|
||||
if (!StringUtils.isBlank(user.getLanguage())) {
|
||||
userLocale = new Locale(user.getLanguage());
|
||||
}
|
||||
UserSession session = userSessionManager.createSession(user, userLocale, false);
|
||||
if (user.getDefaultSubstitutedUser() != null) {
|
||||
session = userSessionManager.createSession(session, user.getDefaultSubstitutedUser());
|
||||
}
|
||||
log.info("Logged in: " + session);
|
||||
|
||||
tx.commit();
|
||||
|
||||
userSessionManager.storeSession(session);
|
||||
|
||||
return session;
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale, Map<String, Object> params)
|
||||
throws LoginException {
|
||||
return loginByRememberMe(login, rememberMeToken, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
try {
|
||||
@ -261,6 +318,7 @@ public class LoginWorkerBean implements LoginWorker {
|
||||
@Override
|
||||
public UserSession getSession(UUID sessionId) {
|
||||
try {
|
||||
//noinspection UnnecessaryLocalVariable
|
||||
UserSession session = userSessionManager.getSession(sessionId);
|
||||
return session;
|
||||
} catch (RuntimeException e) {
|
||||
@ -270,4 +328,28 @@ public class LoginWorkerBean implements LoginWorker {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
boolean verified = false;
|
||||
|
||||
Transaction tx = persistence.createTransaction();
|
||||
try {
|
||||
EntityManager em = persistence.getEntityManager();
|
||||
TypedQuery<RememberMeToken> query = em.createQuery(
|
||||
"select rt from sec$RememberMeToken rt where rt.token = :token and rt.user.loginLowerCase = :userLogin",
|
||||
RememberMeToken.class);
|
||||
query.setParameter("token", rememberMeToken);
|
||||
query.setParameter("userLogin", StringUtils.lowerCase(login));
|
||||
|
||||
if (query.getFirstResult() != null) {
|
||||
verified = true;
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
return verified;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import groovy.text.SimpleTemplateEngine;
|
||||
import groovy.text.Template;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@ -219,10 +220,57 @@ public class UserManagementServiceBean implements UserManagementService {
|
||||
return passwordEncryption.checkPassword(user, passwordHash);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean checkEqualsOfNewAndOldPassword(UUID userId, String newPasswordHash) {
|
||||
return checkPassword(userId, newPasswordHash);
|
||||
public void resetRememberMeTokens(List<UUID> userIds) {
|
||||
Transaction tx = persistence.getTransaction();
|
||||
try {
|
||||
EntityManager em = persistence.getEntityManager();
|
||||
|
||||
Query query = em.createQuery("delete from sec$RememberMeToken rt where rt.user.id in :userIds");
|
||||
query.setParameter("userIds", userIds);
|
||||
query.executeUpdate();
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetRememberMeTokens() {
|
||||
Transaction tx = persistence.createTransaction();
|
||||
try {
|
||||
EntityManager em = persistence.getEntityManager();
|
||||
|
||||
Query query = em.createQuery("delete from sec$RememberMeToken rt");
|
||||
query.executeUpdate();
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateRememberMeToken(UUID userId) {
|
||||
String token = RandomStringUtils.randomAlphanumeric(RememberMeToken.TOKEN_LENGTH);
|
||||
|
||||
Transaction tx = persistence.createTransaction();
|
||||
try {
|
||||
EntityManager em = persistence.getEntityManager();
|
||||
|
||||
RememberMeToken rememberMeToken = new RememberMeToken();
|
||||
rememberMeToken.setToken(token);
|
||||
rememberMeToken.setUser(em.getReference(User.class, userId));
|
||||
|
||||
em.persist(rememberMeToken);
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
protected EmailTemplate getResetPasswordTemplate(User user,
|
||||
@ -357,10 +405,13 @@ public class UserManagementServiceBean implements UserManagementService {
|
||||
modifiedUsers.put(user, password);
|
||||
}
|
||||
|
||||
resetRememberMeTokens(userIds);
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
|
||||
return modifiedUsers;
|
||||
}
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 736 B |
@ -67,7 +67,31 @@ public interface LoginService {
|
||||
* @return created user session
|
||||
* @throws LoginException in case of unsuccessful login
|
||||
*/
|
||||
UserSession loginTrusted(String login, String password, Locale locale, Map<String, Object> params) throws LoginException;
|
||||
UserSession loginTrusted(String login, String password, Locale locale, Map<String, Object> params)
|
||||
throws LoginException;
|
||||
|
||||
/**
|
||||
* Login using user name and remember me token
|
||||
*
|
||||
* @param login login name
|
||||
* @param rememberMeToken client's remember me token
|
||||
* @param locale client locale
|
||||
* @return created user session
|
||||
* @throws LoginException in case of unsuccessful login
|
||||
*/
|
||||
UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* Login using user name and remember me token
|
||||
*
|
||||
* @param login login name
|
||||
* @param rememberMeToken client's remember me token
|
||||
* @param locale client locale
|
||||
* @param params login params
|
||||
* @return created user session
|
||||
* @throws LoginException in case of unsuccessful login
|
||||
*/
|
||||
UserSession loginByRememberMe(String login, String rememberMeToken, Locale locale, Map<String, Object> params) throws LoginException;
|
||||
|
||||
/**
|
||||
* Log out and destroy an active user session.
|
||||
@ -79,7 +103,7 @@ public interface LoginService {
|
||||
* <p/>
|
||||
* This method replaces an active UserSession with the new one, which is returned.
|
||||
*
|
||||
* @param substitutedUser a user to substitute. Must be in the current users's {@link User#substitutions} list.
|
||||
* @param substitutedUser a user to substitute. Must be in the current users' {@link User#substitutions} list.
|
||||
* @return new UserSession instance that contains: <ul>
|
||||
* <li> id - the previously active user session id </li>
|
||||
* <li> user - the logged in user </li>
|
||||
@ -97,4 +121,13 @@ public interface LoginService {
|
||||
*/
|
||||
@Nullable
|
||||
UserSession getSession(UUID sessionId);
|
||||
|
||||
/**
|
||||
* Check if remember me token exists in db
|
||||
*
|
||||
* @param login user login
|
||||
* @param rememberMeToken remember me token
|
||||
* @return true if remember me token exists in db
|
||||
*/
|
||||
boolean checkRememberMe(String login, String rememberMeToken);
|
||||
}
|
@ -65,11 +65,21 @@ public interface UserManagementService {
|
||||
boolean checkPassword(UUID userId, String passwordHash);
|
||||
|
||||
/**
|
||||
* @param userId User id
|
||||
* @param newPasswordHash Plain hash of new password
|
||||
* @return True if the new and old passwords are equal
|
||||
* @deprecated Use ${@link com.haulmont.cuba.security.app.UserManagementService#checkPassword(java.util.UUID, String)}
|
||||
* Remove remember me tokens for users
|
||||
*
|
||||
* @param userIds User ids
|
||||
*/
|
||||
@Deprecated
|
||||
boolean checkEqualsOfNewAndOldPassword(UUID userId, String newPasswordHash);
|
||||
void resetRememberMeTokens(List<UUID> userIds);
|
||||
|
||||
/**
|
||||
* Remove remember me tokens for all users
|
||||
*/
|
||||
void resetRememberMeTokens();
|
||||
|
||||
/**
|
||||
* Generate and store to DB {@link com.haulmont.cuba.security.entity.RememberMeToken}
|
||||
*
|
||||
* @return token string
|
||||
*/
|
||||
String generateRememberMeToken(UUID userId);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.security.entity;
|
||||
|
||||
import com.haulmont.cuba.core.entity.BaseUuidEntity;
|
||||
import com.haulmont.cuba.core.entity.annotation.SystemLevel;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
@Entity(name = "sec$RememberMeToken")
|
||||
@Table(name = "SEC_REMEMBER_ME")
|
||||
@SystemLevel
|
||||
public class RememberMeToken extends BaseUuidEntity {
|
||||
|
||||
private static final long serialVersionUID = -3757776319150532739L;
|
||||
|
||||
public static final int TOKEN_LENGTH = 32;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_ID", nullable = false)
|
||||
protected User user;
|
||||
|
||||
@Column(name = "TOKEN", nullable = false, length = TOKEN_LENGTH)
|
||||
protected String token;
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
}
|
@ -52,6 +52,7 @@
|
||||
<class>com.haulmont.cuba.core.entity.CategoryAttributeValue</class>
|
||||
|
||||
<class>com.haulmont.cuba.core.entity.JmxInstance</class>
|
||||
<class>com.haulmont.cuba.security.entity.RememberMeToken</class>
|
||||
|
||||
<properties>
|
||||
<property name="openjpa.Log" value="log4j"/>
|
||||
|
@ -12,10 +12,7 @@ import com.haulmont.cuba.gui.WindowManager;
|
||||
import com.haulmont.cuba.gui.WindowParams;
|
||||
import com.haulmont.cuba.gui.app.security.user.edit.UserEditor;
|
||||
import com.haulmont.cuba.gui.app.security.user.resetpasswords.ResetPasswordsDialog;
|
||||
import com.haulmont.cuba.gui.components.AbstractLookup;
|
||||
import com.haulmont.cuba.gui.components.Action;
|
||||
import com.haulmont.cuba.gui.components.Table;
|
||||
import com.haulmont.cuba.gui.components.Window;
|
||||
import com.haulmont.cuba.gui.components.*;
|
||||
import com.haulmont.cuba.gui.components.actions.RemoveAction;
|
||||
import com.haulmont.cuba.gui.data.CollectionDatasource;
|
||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||
@ -58,6 +55,12 @@ public class UserBrowser extends AbstractLookup {
|
||||
@Named("usersTable.changePasswAtLogon")
|
||||
protected Action changePasswAtLogonAction;
|
||||
|
||||
@Named("usersTable.resetRememberMe")
|
||||
protected Action resetRememberMeAction;
|
||||
|
||||
@Inject
|
||||
protected PopupButton additionalActionsBtn;
|
||||
|
||||
@Inject
|
||||
protected UserSession userSession;
|
||||
|
||||
@ -116,6 +119,11 @@ public class UserBrowser extends AbstractLookup {
|
||||
}
|
||||
});
|
||||
|
||||
additionalActionsBtn.addAction(copySettingsAction);
|
||||
additionalActionsBtn.addAction(changePasswAction);
|
||||
additionalActionsBtn.addAction(changePasswAtLogonAction);
|
||||
additionalActionsBtn.addAction(resetRememberMeAction);
|
||||
|
||||
if (WindowParams.MULTI_SELECT.getBool(getContext())) {
|
||||
usersTable.setMultiSelect(true);
|
||||
}
|
||||
@ -136,8 +144,9 @@ public class UserBrowser extends AbstractLookup {
|
||||
List<UserRole> userRoles = new ArrayList<>();
|
||||
for (UserRole oldUserRole : selectedUser.getUserRoles()) {
|
||||
Role oldRole = dataSupplier.reload(oldUserRole.getRole(), "_local");
|
||||
if (BooleanUtils.isTrue(oldRole.getDefaultRole()))
|
||||
if (BooleanUtils.isTrue(oldRole.getDefaultRole())) {
|
||||
continue;
|
||||
}
|
||||
UserRole role = new UserRole();
|
||||
role.setUser(newUser);
|
||||
role.setRole(oldRole);
|
||||
@ -163,6 +172,7 @@ public class UserBrowser extends AbstractLookup {
|
||||
public void copySettings() {
|
||||
Set<User> selected = usersTable.getSelected();
|
||||
if (!selected.isEmpty()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Window copySettingsWindow = openWindow(
|
||||
"sec$User.copySettings",
|
||||
WindowManager.OpenType.DIALOG,
|
||||
@ -208,7 +218,7 @@ public class UserBrowser extends AbstractLookup {
|
||||
boolean sendEmails = resetPasswordsDialog.getSendEmails();
|
||||
boolean generatePasswords = resetPasswordsDialog.getGeneratePasswords();
|
||||
Set<User> users = usersTable.getSelected();
|
||||
resetPasswordsForUsers(users, sendEmails, generatePasswords);
|
||||
resetPasswords(users, sendEmails, generatePasswords);
|
||||
}
|
||||
usersTable.requestFocus();
|
||||
}
|
||||
@ -216,7 +226,7 @@ public class UserBrowser extends AbstractLookup {
|
||||
}
|
||||
}
|
||||
|
||||
private void resetPasswordsForUsers(Set<User> users, boolean sendEmails, boolean generatePasswords) {
|
||||
protected void resetPasswords(Set<User> users, boolean sendEmails, boolean generatePasswords) {
|
||||
List<UUID> usersForModify = new ArrayList<>();
|
||||
for (User user : users) {
|
||||
usersForModify.add(user.getId());
|
||||
@ -251,4 +261,63 @@ public class UserBrowser extends AbstractLookup {
|
||||
usersDs.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public void resetRememberMe() {
|
||||
if (usersTable.getSelected().isEmpty()) {
|
||||
showOptionDialog(getMessage("resetRememberMeTitle"), getMessage("resetRememberMeQuestion"), MessageType.CONFIRMATION,
|
||||
new Action[]{
|
||||
new AbstractAction("actions.ResetAll") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
resetRememberMeAll();
|
||||
}
|
||||
},
|
||||
new AbstractAction("actions.Cancel") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
showOptionDialog(getMessage("resetRememberMeTitle"), getMessage("resetRememberMeQuestion"), MessageType.CONFIRMATION,
|
||||
new Action[]{
|
||||
new AbstractAction("actions.ResetSelected") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
resetRememberMe(usersTable.<User>getSelected());
|
||||
}
|
||||
},
|
||||
new AbstractAction("actions.ResetAll") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
resetRememberMeAll();
|
||||
}
|
||||
},
|
||||
new AbstractAction("actions.Cancel") {
|
||||
@Override
|
||||
public void actionPerform(Component component) {
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetRememberMe(Set<User> users) {
|
||||
List<UUID> usersForModify = new ArrayList<>();
|
||||
for (User user : users) {
|
||||
usersForModify.add(user.getId());
|
||||
}
|
||||
|
||||
userManagementService.resetRememberMeTokens(usersForModify);
|
||||
|
||||
showNotification(getMessage("resetRememberMeCompleted"), NotificationType.HUMANIZED);
|
||||
}
|
||||
|
||||
public void resetRememberMeAll() {
|
||||
userManagementService.resetRememberMeTokens();
|
||||
|
||||
showNotification(getMessage("resetRememberMeCompleted"), NotificationType.HUMANIZED);
|
||||
}
|
||||
}
|
@ -26,4 +26,13 @@ filter.customSuperRole=Has super role
|
||||
filter.Language=Language
|
||||
Language=Language
|
||||
|
||||
copySettings=Copy settings
|
||||
copySettings=Copy settings
|
||||
additional=Additional
|
||||
resetRememberMe=Reset 'remember me' tokens
|
||||
resetRememberMeTitle=Reset 'remember me' tokens for users
|
||||
resetRememberMeQuestion=Reset tokens for all users?
|
||||
resetRememberMeCompleted='Remember me' tokens have been removed
|
||||
|
||||
actions.Reset=Reset
|
||||
actions.ResetAll=Reset for all
|
||||
actions.ResetSelected=Reset for selected
|
@ -22,4 +22,13 @@ Language=Язык
|
||||
copySettings=Копировать настройки
|
||||
changePasswAtLogon=Сброс паролей
|
||||
resetPasswordCompleted=Сброс пароля запланирован для %s пользователей
|
||||
changePasswordAtLogonCompleted=Применено к %s пользователям
|
||||
changePasswordAtLogonCompleted=Применено к %s пользователям
|
||||
additional=Дополнительно
|
||||
resetRememberMe=Сброс токенов 'Запомнить меня'
|
||||
resetRememberMeTitle=Сбросить токены 'Запомнить меня'
|
||||
resetRememberMeQuestion=Сбросить токены 'Запомнить меня' для всех пользователей?
|
||||
resetRememberMeCompleted=Токены 'Запомнить меня' удалены
|
||||
|
||||
actions.Reset=Сбросить
|
||||
actions.ResetAll=Сбросить для всех
|
||||
actions.ResetSelected=Сбросить для выбранных
|
@ -41,12 +41,10 @@
|
||||
<action id="edit"/>
|
||||
<action id="copy" caption="msg://copy" icon="icons/copy.png" invoke="copy" enable="false"/>
|
||||
<action id="remove"/>
|
||||
<action id="copySettings" caption="msg://copySettings" icon="icons/copy.png"
|
||||
invoke="copySettings"/>
|
||||
<action id="changePassw" caption="msg://changePassw" icon="icons/change-pass.png"
|
||||
invoke="changePassword"/>
|
||||
<action id="changePasswAtLogon" caption="msg://changePasswAtLogon" icon="icons/change-pass-at-logon.png"
|
||||
invoke="changePasswordAtLogon"/>
|
||||
<action id="copySettings" caption="msg://copySettings" invoke="copySettings"/>
|
||||
<action id="changePassw" caption="msg://changePassw" invoke="changePassword"/>
|
||||
<action id="changePasswAtLogon" caption="msg://changePasswAtLogon" invoke="changePasswordAtLogon"/>
|
||||
<action id="resetRememberMe" caption="msg://resetRememberMe" invoke="resetRememberMe"/>
|
||||
<action id="excel"/>
|
||||
</actions>
|
||||
<buttonsPanel>
|
||||
@ -54,9 +52,7 @@
|
||||
<button action="usersTable.edit"/>
|
||||
<button id="userTableCopyButton" action="usersTable.copy"/>
|
||||
<button action="usersTable.remove"/>
|
||||
<button action="usersTable.copySettings"/>
|
||||
<button id="changePasswordButton" action="usersTable.changePassw"/>
|
||||
<button action="usersTable.changePasswAtLogon"/>
|
||||
<popupButton id="additionalActionsBtn" caption="msg://additional" icon="icons/gear.png"/>
|
||||
<button action="usersTable.excel"/>
|
||||
</buttonsPanel>
|
||||
<rowsCount/>
|
||||
|
@ -15,6 +15,7 @@ import org.apache.commons.lang.ObjectUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -128,6 +129,9 @@ public class UserChangePassw extends AbstractEditor {
|
||||
@Override
|
||||
protected boolean postCommit(boolean committed, boolean close) {
|
||||
if (committed) {
|
||||
UUID userId = userDs.getItem().getId();
|
||||
userManagementService.resetRememberMeTokens(Collections.singletonList(userId));
|
||||
|
||||
showNotification(getMessage("passwordChanged"), NotificationType.HUMANIZED);
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,22 @@ public class CASProtectedConnection extends AbstractConnection {
|
||||
update(loginService.login(login, password, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
if (locale == null)
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
|
||||
update(loginService.loginByRememberMe(login, rememberMeToken, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String logout() {
|
||||
super.logout();
|
||||
return "logout";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
return loginService.checkRememberMe(login, rememberMeToken);
|
||||
}
|
||||
}
|
@ -24,10 +24,19 @@ public interface Connection {
|
||||
* @param login user login name
|
||||
* @param password encrypted user password
|
||||
* @param locale user locale
|
||||
* @throws LoginException in case of unsuccesful login due to wrong credentials or other issues
|
||||
* @throws LoginException in case of unsuccessful login due to wrong credentials or other issues
|
||||
*/
|
||||
void login(String login, String password, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* Log in to the system.
|
||||
* @param login user login name
|
||||
* @param rememberMeToken remember me token
|
||||
* @param locale user locale
|
||||
* @throws LoginException in case of unsuccessful login due to wrong credentials or other issues
|
||||
*/
|
||||
void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* Log out of the system.
|
||||
* Returns URL to which the user will be redirected after logout.
|
||||
@ -50,6 +59,15 @@ public interface Connection {
|
||||
*/
|
||||
boolean isConnected();
|
||||
|
||||
/**
|
||||
* Check if remember me token exists in db
|
||||
*
|
||||
* @param login user login
|
||||
* @param rememberMeToken remember me token
|
||||
* @return true if remember me token exists in db
|
||||
*/
|
||||
boolean checkRememberMe(String login, String rememberMeToken);
|
||||
|
||||
/**
|
||||
* Get current user session.
|
||||
* @return user session object or null if not connected
|
||||
@ -60,7 +78,7 @@ public interface Connection {
|
||||
/**
|
||||
* Update internal state with the passed user session object. Also fires connection listeners.
|
||||
* @param session new UserSession object
|
||||
* @throws LoginException in case of unsuccesful update
|
||||
* @throws LoginException in case of unsuccessful update
|
||||
*/
|
||||
void update(UserSession session) throws LoginException;
|
||||
|
||||
@ -87,4 +105,4 @@ public interface Connection {
|
||||
* @param listener listener to remove
|
||||
*/
|
||||
void removeListener(UserSubstitutionListener listener);
|
||||
}
|
||||
}
|
@ -26,16 +26,27 @@ public class DefaultConnection extends AbstractConnection implements ActiveDirec
|
||||
|
||||
@Override
|
||||
public void login(String login, String password, Locale locale) throws LoginException {
|
||||
if (locale == null)
|
||||
if (locale == null) {
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
}
|
||||
|
||||
update(loginService.login(login, password, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginActiveDirectory(String login, Locale locale) throws LoginException {
|
||||
if (locale == null)
|
||||
public void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
if (locale == null) {
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
}
|
||||
|
||||
update(loginService.loginByRememberMe(login, rememberMeToken, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginActiveDirectory(String login, Locale locale) throws LoginException {
|
||||
if (locale == null) {
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
}
|
||||
|
||||
String password = configuration.getConfig(WebAuthConfig.class).getTrustedClientPassword();
|
||||
update(loginService.loginTrusted(login, password, locale));
|
||||
@ -44,6 +55,11 @@ public class DefaultConnection extends AbstractConnection implements ActiveDirec
|
||||
@Override
|
||||
public String logout() {
|
||||
super.logout();
|
||||
return ActiveDirectoryHelper.useActiveDirectory()? "login" : "";
|
||||
return ActiveDirectoryHelper.useActiveDirectory() ? "login" : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
return loginService.checkRememberMe(login, rememberMeToken);
|
||||
}
|
||||
}
|
@ -8,9 +8,13 @@ import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.gui.AppConfig;
|
||||
import com.haulmont.cuba.gui.ComponentsHelper;
|
||||
import com.haulmont.cuba.gui.TestIdManager;
|
||||
import com.haulmont.cuba.security.app.UserManagementService;
|
||||
import com.haulmont.cuba.security.entity.User;
|
||||
import com.haulmont.cuba.security.global.LoginException;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import com.haulmont.cuba.web.auth.ActiveDirectoryConnection;
|
||||
import com.haulmont.cuba.web.auth.ActiveDirectoryHelper;
|
||||
import com.haulmont.cuba.web.auth.CubaAuthProvider;
|
||||
import com.haulmont.cuba.web.auth.DomainAliasesResolver;
|
||||
import com.haulmont.cuba.web.sys.Browser;
|
||||
import com.haulmont.cuba.web.toolkit.VersionedThemeResource;
|
||||
@ -25,16 +29,12 @@ import com.vaadin.server.VaadinSession;
|
||||
import com.vaadin.server.WebBrowser;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.*;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
@ -59,12 +59,6 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
|
||||
private static final char[] DOMAIN_SEPARATORS = new char[]{'\\', '@'};
|
||||
|
||||
/**
|
||||
* This key is used to encrypt password in cookie to support "remember me" in AD auth.
|
||||
* Must be of 8 symbols.
|
||||
*/
|
||||
private static final String PASSWORD_KEY = "25tuThUw";
|
||||
|
||||
protected Connection connection;
|
||||
|
||||
protected final AppUI ui;
|
||||
@ -95,6 +89,8 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
protected Configuration configuration;
|
||||
protected PasswordEncryption passwordEncryption;
|
||||
|
||||
protected UserManagementService userManagementService;
|
||||
|
||||
public LoginWindow(AppUI ui) {
|
||||
log.trace("Creating " + this);
|
||||
this.ui = ui;
|
||||
@ -102,6 +98,7 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
configuration = AppBeans.get(Configuration.NAME);
|
||||
messages = AppBeans.get(Messages.NAME);
|
||||
passwordEncryption = AppBeans.get(PasswordEncryption.NAME);
|
||||
userManagementService = AppBeans.get(UserManagementService.NAME);
|
||||
|
||||
globalConfig = configuration.getConfig(GlobalConfig.class);
|
||||
webConfig = configuration.getConfig(WebConfig.class);
|
||||
@ -300,11 +297,8 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
}
|
||||
|
||||
protected void initRememberMe() {
|
||||
App app = App.getInstance();
|
||||
String rememberMeCookie = app.getCookieValue(COOKIE_REMEMBER_ME);
|
||||
if (Boolean.parseBoolean(rememberMeCookie)) {
|
||||
rememberMe.setValue(true);
|
||||
|
||||
String login;
|
||||
String encodedLogin = app.getCookieValue(COOKIE_LOGIN) != null ? app.getCookieValue(COOKIE_LOGIN) : "";
|
||||
try {
|
||||
@ -313,9 +307,14 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
login = encodedLogin;
|
||||
}
|
||||
|
||||
loginField.setValue(login);
|
||||
passwordField.setValue(app.getCookieValue(COOKIE_PASSWORD) != null ? app.getCookieValue(COOKIE_PASSWORD) : "");
|
||||
loginByRememberMe = true;
|
||||
String rememberMeToken = app.getCookieValue(COOKIE_PASSWORD) != null ? app.getCookieValue(COOKIE_PASSWORD) : "";
|
||||
if (connection.checkRememberMe(login, rememberMeToken)) {
|
||||
rememberMe.setValue(true);
|
||||
loginField.setValue(login);
|
||||
|
||||
passwordField.setValue(rememberMeToken);
|
||||
loginByRememberMe = true;
|
||||
}
|
||||
|
||||
loginChangeListener = new Property.ValueChangeListener() {
|
||||
@Override
|
||||
@ -335,37 +334,42 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
protected void initFields() {
|
||||
String currLocale = messages.getTools().localeToString(resolvedLocale);
|
||||
String selected = null;
|
||||
App app = App.getInstance();
|
||||
for (Map.Entry<String, Locale> entry : locales.entrySet()) {
|
||||
localesSelect.addItem(entry.getKey());
|
||||
if (messages.getTools().localeToString(entry.getValue()).equals(currLocale))
|
||||
if (messages.getTools().localeToString(entry.getValue()).equals(currLocale)) {
|
||||
selected = entry.getKey();
|
||||
}
|
||||
}
|
||||
if (selected == null)
|
||||
if (selected == null) {
|
||||
selected = locales.keySet().iterator().next();
|
||||
}
|
||||
localesSelect.setValue(selected);
|
||||
|
||||
if (ActiveDirectoryHelper.useActiveDirectory()) {
|
||||
loginField.setValue(app.getPrincipal() == null ? "" : app.getPrincipal().getName());
|
||||
passwordField.setValue("");
|
||||
|
||||
if (rememberMeAllowed && !ActiveDirectoryHelper.activeDirectorySupportedBySession())
|
||||
if (rememberMeAllowed && !ActiveDirectoryHelper.activeDirectorySupportedBySession()) {
|
||||
initRememberMe();
|
||||
}
|
||||
} else {
|
||||
String defaultUser = webConfig.getLoginDialogDefaultUser();
|
||||
if (!StringUtils.isBlank(defaultUser) && !"<disabled>".equals(defaultUser))
|
||||
if (!StringUtils.isBlank(defaultUser) && !"<disabled>".equals(defaultUser)) {
|
||||
loginField.setValue(defaultUser);
|
||||
else
|
||||
} else {
|
||||
loginField.setValue("");
|
||||
}
|
||||
|
||||
String defaultPassw = webConfig.getLoginDialogDefaultPassword();
|
||||
if (!StringUtils.isBlank(defaultPassw) && !"<disabled>".equals(defaultPassw))
|
||||
if (!StringUtils.isBlank(defaultPassw) && !"<disabled>".equals(defaultPassw)) {
|
||||
passwordField.setValue(defaultPassw);
|
||||
else
|
||||
} else {
|
||||
passwordField.setValue("");
|
||||
}
|
||||
|
||||
if (rememberMeAllowed)
|
||||
if (rememberMeAllowed) {
|
||||
initRememberMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,27 +403,21 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
protected void login() {
|
||||
String login = loginField.getValue();
|
||||
try {
|
||||
// Login with AD if domain specified
|
||||
if (ActiveDirectoryHelper.useActiveDirectory() && StringUtils.containsAny(login, DOMAIN_SEPARATORS)) {
|
||||
Locale locale = getUserLocale();
|
||||
App.getInstance().setLocale(locale);
|
||||
Locale locale = getUserLocale();
|
||||
app.setLocale(locale);
|
||||
|
||||
String password = passwordField.getValue();
|
||||
if (loginByRememberMe && StringUtils.isNotEmpty(password))
|
||||
password = decryptPassword(password);
|
||||
String passwordValue = passwordField.getValue() != null ? passwordField.getValue() : "";
|
||||
|
||||
ActiveDirectoryHelper.getAuthProvider().authenticate(login, password, resolvedLocale);
|
||||
if (loginByRememberMe && rememberMeAllowed) {
|
||||
loginByRememberMe(login, passwordValue, locale);
|
||||
} else if (ActiveDirectoryHelper.useActiveDirectory() && StringUtils.containsAny(login, DOMAIN_SEPARATORS)) {
|
||||
CubaAuthProvider authProvider = ActiveDirectoryHelper.getAuthProvider();
|
||||
authProvider.authenticate(login, passwordValue, resolvedLocale);
|
||||
login = convertLoginString(login);
|
||||
|
||||
((ActiveDirectoryConnection) connection).loginActiveDirectory(login, locale);
|
||||
} else {
|
||||
Locale locale = getUserLocale();
|
||||
App.getInstance().setLocale(locale);
|
||||
|
||||
String value = passwordField.getValue() != null ? passwordField.getValue() : "";
|
||||
String passwd = loginByRememberMe ? value : passwordEncryption.getPlainHash(value);
|
||||
|
||||
login(login, passwd, locale);
|
||||
login(login, passwordEncryption.getPlainHash(passwordValue), locale);
|
||||
}
|
||||
} catch (LoginException e) {
|
||||
log.info("Login failed: " + e.toString());
|
||||
@ -428,7 +426,7 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
new Notification(
|
||||
ComponentsHelper.preprocessHtmlMessage(message),
|
||||
StringUtils.abbreviate(e.getMessage(), 1000), Notification.Type.ERROR_MESSAGE, true)
|
||||
.show(getUI().getPage());
|
||||
.show(ui.getPage());
|
||||
|
||||
if (loginByRememberMe) {
|
||||
loginByRememberMe = false;
|
||||
@ -464,90 +462,58 @@ public class LoginWindow extends UIView implements Action.Handler {
|
||||
return login;
|
||||
}
|
||||
|
||||
protected void login(String login, String passwd, Locale locale) throws LoginException {
|
||||
connection.login(login, passwd, locale);
|
||||
protected void login(String login, String password, Locale locale) throws LoginException {
|
||||
connection.login(login, password, locale);
|
||||
}
|
||||
|
||||
protected void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
connection.loginByRememberMe(login, rememberMeToken, locale);
|
||||
}
|
||||
|
||||
protected void doLogin() {
|
||||
login();
|
||||
if (rememberMeAllowed) {
|
||||
App app = App.getInstance();
|
||||
if (Boolean.TRUE.equals(rememberMe.getValue())) {
|
||||
if (!loginByRememberMe) {
|
||||
app.addCookie(COOKIE_REMEMBER_ME, String.valueOf(rememberMe.getValue()));
|
||||
|
||||
String login = loginField.getValue();
|
||||
String password = passwordField.getValue() != null ? passwordField.getValue() : "";
|
||||
if (connection.isConnected()) {
|
||||
if (rememberMeAllowed) {
|
||||
if (Boolean.TRUE.equals(rememberMe.getValue())) {
|
||||
if (!loginByRememberMe) {
|
||||
app.addCookie(COOKIE_REMEMBER_ME, Boolean.TRUE.toString());
|
||||
|
||||
String encodedLogin;
|
||||
try {
|
||||
encodedLogin = URLEncoder.encode(login, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
encodedLogin = login;
|
||||
}
|
||||
|
||||
app.addCookie(COOKIE_LOGIN, StringEscapeUtils.escapeJava(encodedLogin));
|
||||
if (!ActiveDirectoryHelper.useActiveDirectory())
|
||||
app.addCookie(COOKIE_PASSWORD, passwordEncryption.getPlainHash(password));
|
||||
else {
|
||||
if (StringUtils.isNotEmpty(password))
|
||||
app.addCookie(COOKIE_PASSWORD, encryptPassword(password));
|
||||
String login = loginField.getValue();
|
||||
|
||||
String encodedLogin;
|
||||
try {
|
||||
encodedLogin = URLEncoder.encode(login, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
encodedLogin = login;
|
||||
}
|
||||
|
||||
app.addCookie(COOKIE_LOGIN, StringEscapeUtils.escapeJava(encodedLogin));
|
||||
|
||||
UserSession session = connection.getSession();
|
||||
if (session == null) {
|
||||
throw new IllegalStateException("Unable to get session after login");
|
||||
}
|
||||
|
||||
User user = session.getUser();
|
||||
|
||||
String rememberMeToken = userManagementService.generateRememberMeToken(user.getId());
|
||||
|
||||
app.addCookie(COOKIE_PASSWORD, rememberMeToken);
|
||||
}
|
||||
} else {
|
||||
app.removeCookie(COOKIE_REMEMBER_ME);
|
||||
app.removeCookie(COOKIE_LOGIN);
|
||||
app.removeCookie(COOKIE_PASSWORD);
|
||||
}
|
||||
} else {
|
||||
app.removeCookie(COOKIE_REMEMBER_ME);
|
||||
app.removeCookie(COOKIE_LOGIN);
|
||||
app.removeCookie(COOKIE_PASSWORD);
|
||||
}
|
||||
|
||||
if (webConfig.getUseSessionFixationProtection()) {
|
||||
VaadinService.reinitializeSession(VaadinService.getCurrentRequest());
|
||||
|
||||
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(webConfig.getHttpSessionExpirationTimeoutSec());
|
||||
}
|
||||
}
|
||||
|
||||
if (webConfig.getUseSessionFixationProtection()) {
|
||||
VaadinService.reinitializeSession(VaadinService.getCurrentRequest());
|
||||
|
||||
VaadinSession.getCurrent().getSession().setMaxInactiveInterval(webConfig.getHttpSessionExpirationTimeoutSec());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt password to store in cookie for "remember me". <br/>
|
||||
* Used only for AD auth.
|
||||
*
|
||||
* @param password plain password
|
||||
* @return encrypted password
|
||||
*/
|
||||
protected String encryptPassword(String password) {
|
||||
SecretKeySpec key = new SecretKeySpec(PASSWORD_KEY.getBytes(), "DES");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(PASSWORD_KEY.getBytes());
|
||||
String result;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
|
||||
result = new String(Hex.encodeHex(cipher.doFinal(password.getBytes())));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the password stored in cookie. <br/>
|
||||
* Used only for AD auth.
|
||||
*
|
||||
* @param password encrypted password
|
||||
* @return plain password, or input string if decryption fails
|
||||
*/
|
||||
protected String decryptPassword(String password) {
|
||||
SecretKeySpec key = new SecretKeySpec(PASSWORD_KEY.getBytes(), "DES");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(PASSWORD_KEY.getBytes());
|
||||
String result;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
|
||||
result = new String(cipher.doFinal(Hex.decodeHex(password.toCharArray())));
|
||||
} catch (Exception e) {
|
||||
return password;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Locale getUserLocale() {
|
||||
|
BIN
modules/web/themes/havana/icons/gear.png
Normal file
BIN
modules/web/themes/havana/icons/gear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 736 B |
@ -24,9 +24,22 @@ public class CASProtectedConnection extends AbstractConnection {
|
||||
update(loginService.login(login, password, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
if (locale == null)
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
|
||||
update(loginService.loginByRememberMe(login, rememberMeToken, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String logout() {
|
||||
super.logout();
|
||||
return "logout";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
return loginService.checkRememberMe(login, rememberMeToken);
|
||||
}
|
||||
}
|
@ -14,9 +14,8 @@ import java.util.Locale;
|
||||
/**
|
||||
* Interface to be implemented by middleware connection objects on web-client.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Connection {
|
||||
|
||||
@ -25,10 +24,19 @@ public interface Connection {
|
||||
* @param login user login name
|
||||
* @param password encrypted user password
|
||||
* @param locale user locale
|
||||
* @throws LoginException in case of unsuccesful login due to wrong credentials or other issues
|
||||
* @throws LoginException in case of unsuccessful login due to wrong credentials or other issues
|
||||
*/
|
||||
void login(String login, String password, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* Log in to the system.
|
||||
* @param login user login name
|
||||
* @param rememberMeToken remember me token
|
||||
* @param locale user locale
|
||||
* @throws LoginException in case of unsuccessful login due to wrong credentials or other issues
|
||||
*/
|
||||
void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException;
|
||||
|
||||
/**
|
||||
* Log out of the system.
|
||||
* Returns URL to which the user will be redirected after logout.
|
||||
@ -51,6 +59,15 @@ public interface Connection {
|
||||
*/
|
||||
boolean isConnected();
|
||||
|
||||
/**
|
||||
* Check if remember me token exists in db
|
||||
*
|
||||
* @param login user login
|
||||
* @param rememberMeToken remember me token
|
||||
* @return true if remember me token exists in db
|
||||
*/
|
||||
boolean checkRememberMe(String login, String rememberMeToken);
|
||||
|
||||
/**
|
||||
* Get current user session.
|
||||
* @return user session object or null if not connected
|
||||
@ -61,7 +78,7 @@ public interface Connection {
|
||||
/**
|
||||
* Update internal state with the passed user session object. Also fires connection listeners.
|
||||
* @param session new UserSession object
|
||||
* @throws LoginException in case of unsuccesful update
|
||||
* @throws LoginException in case of unsuccessful update
|
||||
*/
|
||||
void update(UserSession session) throws LoginException;
|
||||
|
||||
@ -88,4 +105,4 @@ public interface Connection {
|
||||
* @param listener listener to remove
|
||||
*/
|
||||
void removeListener(UserSubstitutionListener listener);
|
||||
}
|
||||
}
|
@ -32,6 +32,15 @@ public class DefaultConnection extends AbstractConnection implements ActiveDirec
|
||||
update(loginService.login(login, password, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
if (locale == null) {
|
||||
throw new IllegalArgumentException("Locale is null");
|
||||
}
|
||||
|
||||
update(loginService.loginByRememberMe(login, rememberMeToken, locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginActiveDirectory(String login, Locale locale) throws LoginException {
|
||||
if (locale == null)
|
||||
@ -46,4 +55,9 @@ public class DefaultConnection extends AbstractConnection implements ActiveDirec
|
||||
super.logout();
|
||||
return ActiveDirectoryHelper.useActiveDirectory()? "login" : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRememberMe(String login, String rememberMeToken) {
|
||||
return loginService.checkRememberMe(login, rememberMeToken);
|
||||
}
|
||||
}
|
@ -7,9 +7,13 @@ package com.haulmont.cuba.web;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.gui.AppConfig;
|
||||
import com.haulmont.cuba.gui.ComponentsHelper;
|
||||
import com.haulmont.cuba.security.app.UserManagementService;
|
||||
import com.haulmont.cuba.security.entity.User;
|
||||
import com.haulmont.cuba.security.global.LoginException;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import com.haulmont.cuba.web.auth.ActiveDirectoryConnection;
|
||||
import com.haulmont.cuba.web.auth.ActiveDirectoryHelper;
|
||||
import com.haulmont.cuba.web.auth.CubaAuthProvider;
|
||||
import com.haulmont.cuba.web.auth.DomainAliasesResolver;
|
||||
import com.haulmont.cuba.web.sys.Browser;
|
||||
import com.haulmont.cuba.web.sys.CubaApplicationContext;
|
||||
@ -20,16 +24,12 @@ import com.vaadin.event.ShortcutAction;
|
||||
import com.vaadin.terminal.gwt.server.WebApplicationContext;
|
||||
import com.vaadin.terminal.gwt.server.WebBrowser;
|
||||
import com.vaadin.ui.*;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
@ -56,12 +56,6 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
|
||||
private static final char[] DOMAIN_SEPARATORS = new char[]{'\\', '@'};
|
||||
|
||||
/**
|
||||
* This key is used to encrypt password in cookie to support "remember me" in AD auth.
|
||||
* Must be of 8 symbols.
|
||||
*/
|
||||
private static final String PASSWORD_KEY = "25tuThUw";
|
||||
|
||||
protected Connection connection;
|
||||
|
||||
protected TextField loginField;
|
||||
@ -84,12 +78,15 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
protected Configuration configuration;
|
||||
protected PasswordEncryption passwordEncryption;
|
||||
|
||||
protected UserManagementService userManagementService;
|
||||
|
||||
public LoginWindow(App app, Connection connection) {
|
||||
log.trace("Creating " + this);
|
||||
|
||||
configuration = AppBeans.get(Configuration.NAME);
|
||||
messages = AppBeans.get(Messages.NAME);
|
||||
passwordEncryption = AppBeans.get(PasswordEncryption.NAME);
|
||||
userManagementService = AppBeans.get(UserManagementService.NAME);
|
||||
|
||||
globalConfig = configuration.getConfig(GlobalConfig.class);
|
||||
webConfig = configuration.getConfig(WebConfig.class);
|
||||
@ -285,8 +282,6 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
|
||||
String rememberMeCookie = app.getCookieValue(COOKIE_REMEMBER_ME);
|
||||
if (Boolean.parseBoolean(rememberMeCookie)) {
|
||||
rememberMe.setValue(true);
|
||||
|
||||
String login;
|
||||
String encodedLogin = app.getCookieValue(COOKIE_LOGIN) != null ? app.getCookieValue(COOKIE_LOGIN) : "";
|
||||
try {
|
||||
@ -295,9 +290,14 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
login = encodedLogin;
|
||||
}
|
||||
|
||||
loginField.setValue(login);
|
||||
passwordField.setValue(app.getCookieValue(COOKIE_PASSWORD) != null ? app.getCookieValue(COOKIE_PASSWORD) : "");
|
||||
loginByRememberMe = true;
|
||||
String rememberMeToken = app.getCookieValue(COOKIE_PASSWORD) != null ? app.getCookieValue(COOKIE_PASSWORD) : "";
|
||||
if (connection.checkRememberMe(login, rememberMeToken)) {
|
||||
rememberMe.setValue(true);
|
||||
loginField.setValue(login);
|
||||
|
||||
passwordField.setValue(rememberMeToken);
|
||||
loginByRememberMe = true;
|
||||
}
|
||||
|
||||
loginChangeListener = new Property.ValueChangeListener() {
|
||||
@Override
|
||||
@ -374,24 +374,21 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
protected void login() {
|
||||
String login = (String) loginField.getValue();
|
||||
try {
|
||||
// Login with AD if domain specified
|
||||
if (ActiveDirectoryHelper.useActiveDirectory() && StringUtils.containsAny(login, DOMAIN_SEPARATORS)) {
|
||||
Locale locale = getUserLocale();
|
||||
App.getInstance().setLocale(locale);
|
||||
String password = (String) passwordField.getValue();
|
||||
if (loginByRememberMe && StringUtils.isNotEmpty(password))
|
||||
password = decryptPassword(password);
|
||||
Locale locale = getUserLocale();
|
||||
App.getInstance().setLocale(locale);
|
||||
|
||||
ActiveDirectoryHelper.getAuthProvider().authenticate(login, password, resolvedLocale);
|
||||
String passwordValue = passwordField.getValue() != null ? (String) passwordField.getValue() : "";
|
||||
|
||||
if (loginByRememberMe && rememberMe != null) {
|
||||
loginByRememberMe(login, passwordValue, locale);
|
||||
} else if (ActiveDirectoryHelper.useActiveDirectory() && StringUtils.containsAny(login, DOMAIN_SEPARATORS)) {
|
||||
CubaAuthProvider authProvider = ActiveDirectoryHelper.getAuthProvider();
|
||||
authProvider.authenticate(login, passwordValue, resolvedLocale);
|
||||
login = convertLoginString(login);
|
||||
|
||||
((ActiveDirectoryConnection) connection).loginActiveDirectory(login, locale);
|
||||
} else {
|
||||
String value = passwordField.getValue() != null ? (String) passwordField.getValue() : "";
|
||||
String passwd = loginByRememberMe ? value : passwordEncryption.getPlainHash(value);
|
||||
Locale locale = getUserLocale();
|
||||
App.getInstance().setLocale(locale);
|
||||
login(login, passwd, locale);
|
||||
login(login, passwordEncryption.getPlainHash(passwordValue), locale);
|
||||
}
|
||||
} catch (LoginException e) {
|
||||
log.info("Login failed: " + e.toString());
|
||||
@ -435,91 +432,60 @@ public class LoginWindow extends Window implements Action.Handler {
|
||||
return login;
|
||||
}
|
||||
|
||||
protected void login(String login, String passwd, Locale locale) throws LoginException {
|
||||
connection.login(login, passwd, locale);
|
||||
protected void login(String login, String password, Locale locale) throws LoginException {
|
||||
connection.login(login, password, locale);
|
||||
}
|
||||
|
||||
protected void loginByRememberMe(String login, String rememberMeToken, Locale locale) throws LoginException {
|
||||
connection.loginByRememberMe(login, rememberMeToken, locale);
|
||||
}
|
||||
|
||||
protected void doLogin() {
|
||||
login();
|
||||
if (rememberMe != null) {
|
||||
App app = App.getInstance();
|
||||
if (Boolean.TRUE.equals(rememberMe.getValue())) {
|
||||
if (!loginByRememberMe) {
|
||||
app.addCookie(COOKIE_REMEMBER_ME, String.valueOf(rememberMe));
|
||||
|
||||
String login = (String) loginField.getValue();
|
||||
String password = passwordField.getValue() != null ? (String) passwordField.getValue() : "";
|
||||
if (connection.isConnected()) {
|
||||
if (rememberMe != null) {
|
||||
App app = App.getInstance();
|
||||
if (Boolean.TRUE.equals(rememberMe.getValue())) {
|
||||
if (!loginByRememberMe) {
|
||||
app.addCookie(COOKIE_REMEMBER_ME, Boolean.TRUE.toString());
|
||||
|
||||
String encodedLogin;
|
||||
try {
|
||||
encodedLogin = URLEncoder.encode(login, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
encodedLogin = login;
|
||||
}
|
||||
|
||||
app.addCookie(COOKIE_LOGIN, StringEscapeUtils.escapeJava(encodedLogin));
|
||||
if (!ActiveDirectoryHelper.useActiveDirectory())
|
||||
app.addCookie(COOKIE_PASSWORD, passwordEncryption.getPlainHash(password));
|
||||
else {
|
||||
if (StringUtils.isNotEmpty(password))
|
||||
app.addCookie(COOKIE_PASSWORD, encryptPassword(password));
|
||||
String login = (String) loginField.getValue();
|
||||
|
||||
String encodedLogin;
|
||||
try {
|
||||
encodedLogin = URLEncoder.encode(login, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
encodedLogin = login;
|
||||
}
|
||||
|
||||
app.addCookie(COOKIE_LOGIN, StringEscapeUtils.escapeJava(encodedLogin));
|
||||
|
||||
UserSession session = connection.getSession();
|
||||
if (session == null) {
|
||||
throw new IllegalStateException("Unable to get session after login");
|
||||
}
|
||||
|
||||
User user = session.getUser();
|
||||
|
||||
String rememberMeToken = userManagementService.generateRememberMeToken(user.getId());
|
||||
|
||||
app.addCookie(COOKIE_PASSWORD, rememberMeToken);
|
||||
}
|
||||
} else {
|
||||
app.removeCookie(COOKIE_REMEMBER_ME);
|
||||
app.removeCookie(COOKIE_LOGIN);
|
||||
app.removeCookie(COOKIE_PASSWORD);
|
||||
}
|
||||
} else {
|
||||
app.removeCookie(COOKIE_REMEMBER_ME);
|
||||
app.removeCookie(COOKIE_LOGIN);
|
||||
app.removeCookie(COOKIE_PASSWORD);
|
||||
}
|
||||
|
||||
if (webConfig.getUseSessionFixationProtection()) {
|
||||
CubaApplicationContext context = (CubaApplicationContext) App.getInstance().getContext();
|
||||
context.reinitializeSession();
|
||||
|
||||
context.getHttpSession().setMaxInactiveInterval(webConfig.getHttpSessionExpirationTimeoutSec());
|
||||
}
|
||||
}
|
||||
|
||||
if (webConfig.getUseSessionFixationProtection()) {
|
||||
CubaApplicationContext context = (CubaApplicationContext) App.getInstance().getContext();
|
||||
context.reinitializeSession();
|
||||
|
||||
context.getHttpSession().setMaxInactiveInterval(webConfig.getHttpSessionExpirationTimeoutSec());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt password to store in cookie for "remember me". <br/>
|
||||
* Used only for AD auth.
|
||||
*
|
||||
* @param password plain password
|
||||
* @return encrypted password
|
||||
*/
|
||||
protected String encryptPassword(String password) {
|
||||
SecretKeySpec key = new SecretKeySpec(PASSWORD_KEY.getBytes(), "DES");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(PASSWORD_KEY.getBytes());
|
||||
String result;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
|
||||
result = new String(Hex.encodeHex(cipher.doFinal(password.getBytes())));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the password stored in cookie. <br/>
|
||||
* Used only for AD auth.
|
||||
*
|
||||
* @param password encrypted password
|
||||
* @return plain password, or input string if decryption fails
|
||||
*/
|
||||
protected String decryptPassword(String password) {
|
||||
SecretKeySpec key = new SecretKeySpec(PASSWORD_KEY.getBytes(), "DES");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(PASSWORD_KEY.getBytes());
|
||||
String result;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
|
||||
result = new String(cipher.doFinal(Hex.decodeHex(password.toCharArray())));
|
||||
} catch (Exception e) {
|
||||
return password;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Locale getUserLocale() {
|
||||
|
BIN
modules/web6/themes/havana/icons/gear.png
Normal file
BIN
modules/web6/themes/havana/icons/gear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 759 B |
Loading…
Reference in New Issue
Block a user