Commit da61e4c5 authored by ls1947's avatar ls1947
Browse files

Move 2Fa Login zu SecurityFilter

parent ce748d55
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.dao;
import java.util.List;
import edu.kit.scc.webreg.entity.UserLoginInfoEntity;
public interface UserLoginInfoDao extends BaseDao<UserLoginInfoEntity, Long> {
List<UserLoginInfoEntity> findByUser(Long userId);
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.dao.jpa;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import edu.kit.scc.webreg.dao.UserLoginInfoDao;
import edu.kit.scc.webreg.entity.UserLoginInfoEntity;
@Named
@ApplicationScoped
public class JpaUserLoginInfoDao extends JpaBaseDao<UserLoginInfoEntity, Long> implements UserLoginInfoDao {
@Override
@SuppressWarnings("unchecked")
public List<UserLoginInfoEntity> findByUser(Long userId) {
return em.createQuery("select e from UserLoginInfoEntity e where e.user.id = :userId")
.setParameter("userId", userId).getResultList();
}
@Override
public Class<UserLoginInfoEntity> getEntityClass() {
return UserLoginInfoEntity.class;
}
}
package edu.kit.scc.webreg.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity(name = "UserLoginInfoEntity")
@Table(name = "user_login_info")
public class UserLoginInfoEntity extends AbstractBaseEntity {
private static final long serialVersionUID = 1L;
@ManyToOne(targetEntity = UserEntity.class)
private UserEntity user;
@Enumerated(EnumType.STRING)
private UserLoginInfoStatus loginStatus;
@Column(name = "login_date")
private Date loginDate;
@Column(name = "from", length = 256)
private String from;
@Enumerated(EnumType.STRING)
private UserLoginMethod loginMethod;
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public UserLoginInfoStatus getLoginStatus() {
return loginStatus;
}
public void setLoginStatus(UserLoginInfoStatus loginStatus) {
this.loginStatus = loginStatus;
}
public Date getLoginDate() {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public UserLoginMethod getLoginMethod() {
return loginMethod;
}
public void setLoginMethod(UserLoginMethod loginMethod) {
this.loginMethod = loginMethod;
}
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.entity;
public enum UserLoginInfoStatus {
SUCCESS,
FAILED,
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.entity;
public enum UserLoginMethod {
LOCAL,
HOME_ORG,
HOME_ORG_TWOFA,
TWOFA,
}
......@@ -16,4 +16,6 @@ public interface TwoFaService {
LinotpSimpleResponse checkToken(Long userId, String token) throws TwoFaException;
Boolean hasActiveToken(Long userId) throws TwoFaException;
}
package edu.kit.scc.webreg.service.twofa;
import java.util.List;
import java.util.Map;
import javax.ejb.Stateless;
......@@ -13,6 +14,7 @@ import edu.kit.scc.webreg.service.twofa.linotp.LinotpConnection;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpInitAuthenticatorTokenResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpShowUserResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpSimpleResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpToken;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpTokenResultList;
@Stateless
......@@ -57,6 +59,19 @@ public class TwoFaServiceImpl implements TwoFaService {
return resultList;
}
@Override
public Boolean hasActiveToken(Long userId) throws TwoFaException {
List<LinotpToken> tokenList = findByUserId(userId);
for (LinotpToken token : tokenList) {
if (token.getIsactive()) {
return true;
}
}
return false;
}
@Override
public LinotpSimpleResponse checkToken(Long userId, String token) throws TwoFaException {
UserEntity user = userDao.findById(userId);
......
......@@ -113,7 +113,7 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
return resultParser.parseSimpleResponse(responseString);
......@@ -151,7 +151,7 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
return resultParser.parseInitAuthenticatorTokenResponse(responseString);
......@@ -177,7 +177,7 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
return resultParser.parseSimpleResponse(responseString);
......@@ -203,7 +203,7 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
return resultParser.parseSimpleResponse(responseString);
......@@ -233,7 +233,7 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
return resultParser.parseShowUserResponse(responseString);
......@@ -256,12 +256,12 @@ public class LinotpConnection {
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
logger.trace(responseString);
CookieStore cookieStore = context.getCookieStore();
List<Cookie> cookies = cookieStore.getCookies();
for (Cookie cookie : cookies) {
logger.debug("Cookie {}: {}", cookie.getName(), cookie.getValue());
logger.trace("Cookie {}: {}", cookie.getName(), cookie.getValue());
if (cookie.getName().equalsIgnoreCase("admin_session")) {
adminSession = cookie.getValue();
}
......
......@@ -10,26 +10,21 @@
******************************************************************************/
package edu.kit.scc.webreg.bean;
import java.io.IOException;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.twofa.TwoFaException;
import edu.kit.scc.webreg.service.twofa.TwoFaService;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpInitAuthenticatorTokenResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpSimpleResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpToken;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpTokenResultList;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
......@@ -55,37 +50,18 @@ public class TwoFaUserBean implements Serializable {
@Inject
private FacesMessageGenerator messageGenerator;
@Inject
private ApplicationConfig appConfig;
private UserEntity user;
private LinotpTokenResultList tokenList;
private LinotpInitAuthenticatorTokenResponse createTokenResponse;
public void preRenderView(ComponentSystemEvent ev) {
long elevationTime = 5L * 60L * 1000L;
if (appConfig.getConfigValue("elevation_time") != null) {
elevationTime = Long.parseLong(appConfig.getConfigValue("elevation_time"));
}
if (user == null) {
try {
tokenList = twoFaService.findByUserId(sessionManager.getUserId());
for (LinotpToken token : tokenList) {
if (token.getIsactive() && (sessionManager.getTwoFaElevation() == null ||
(System.currentTimeMillis() - sessionManager.getTwoFaElevation().getTime()) > elevationTime)) {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect("/user/twofa-login.xhtml");
sessionManager.setOriginalRequestPath("/user/twofa.xhtml");
}
}
} catch (TwoFaException e) {
messageGenerator.addErrorMessage("Error", e.toString());
logger.debug("Exception happened", e);
} catch (IOException e) {
logger.warn("Could not redirect client", e);
throw new IllegalArgumentException("redirect failed");
}
user = userService.findById(sessionManager.getUserId());
......
......@@ -40,6 +40,8 @@ import edu.kit.scc.webreg.entity.RoleEntity;
import edu.kit.scc.webreg.service.AdminUserService;
import edu.kit.scc.webreg.service.RoleService;
import edu.kit.scc.webreg.service.reg.PasswordUtil;
import edu.kit.scc.webreg.service.twofa.TwoFaException;
import edu.kit.scc.webreg.service.twofa.TwoFaService;
import edu.kit.scc.webreg.session.SessionManager;
@Named
......@@ -65,6 +67,9 @@ public class SecurityFilter implements Filter {
@Inject
private AdminUserService adminUserService;
@Inject
private TwoFaService twoFaService;
@Inject
private ApplicationConfig appConfig;
......@@ -135,7 +140,65 @@ public class SecurityFilter implements Filter {
if (accessChecker.check(path, roles)) {
request.setAttribute(USER_ID, session.getUserId());
chain.doFilter(servletRequest, servletResponse);
if (path.startsWith("/user/twofa.xhtml")) {
/*
* Pages which require 2fa if there is an active token are handled here
*/
long elevationTime = 5L * 60L * 1000L;
if (appConfig.getConfigValue("elevation_time") != null) {
elevationTime = Long.parseLong(appConfig.getConfigValue("elevation_time"));
}
if (session.getTwoFaElevation() != null &&
(System.currentTimeMillis() - session.getTwoFaElevation().getTime()) < elevationTime) {
// user already elevated
chain.doFilter(servletRequest, servletResponse);
}
else {
try {
if (twoFaService.hasActiveToken(session.getUserId())) {
logger.debug("User from {} not elevated. Redirecting to twofa login page", request.getRemoteAddr());
session.setOriginalRequestPath(getFullURL(request));
request.getServletContext().getRequestDispatcher("/user/twofa-login.xhtml").forward(servletRequest, servletResponse);
}
else {
// user has no active tokens, show page anyway
chain.doFilter(servletRequest, servletResponse);
}
} catch (TwoFaException e) {
logger.warn("Cannot communicate with twofa server", e);
throw new ServletException("There is a problem with 2fa", e);
}
}
}
else if (path.startsWith("/user/important.xhtml")) {
/*
* Pages which always require 2fa are handled here
*/
long elevationTime = 5L * 60L * 1000L;
if (appConfig.getConfigValue("elevation_time") != null) {
elevationTime = Long.parseLong(appConfig.getConfigValue("elevation_time"));
}
if (session.getTwoFaElevation() != null &&
(System.currentTimeMillis() - session.getTwoFaElevation().getTime()) < elevationTime) {
// user already elevated
chain.doFilter(servletRequest, servletResponse);
}
else {
logger.debug("User from {} not elevated. Redirecting to twofa login page", request.getRemoteAddr());
session.setOriginalRequestPath(getFullURL(request));
request.getServletContext().getRequestDispatcher("/user/twofa-login.xhtml").forward(servletRequest, servletResponse);
}
}
else {
/*
* Normal pages are handled here
*/
chain.doFilter(servletRequest, servletResponse);
}
}
else
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not allowed");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment