Commit ce748d55 authored by ls1947's avatar ls1947
Browse files

protect second factor page with second factor

implement check method
parent 327e4315
......@@ -14,4 +14,6 @@ public interface TwoFaService {
LinotpSimpleResponse enableToken(Long userId, String serial) throws TwoFaException;
LinotpSimpleResponse checkToken(Long userId, String token) throws TwoFaException;
}
......@@ -56,6 +56,16 @@ public class TwoFaServiceImpl implements TwoFaService {
return resultList;
}
@Override
public LinotpSimpleResponse checkToken(Long userId, String token) throws TwoFaException {
UserEntity user = userDao.findById(userId);
Map<String, String> configMap = configResolver.resolveConfig(user);
LinotpConnection linotpConnection = new LinotpConnection(configMap);
return linotpConnection.checkToken(user, token);
}
@Override
public LinotpInitAuthenticatorTokenResponse createAuthenticatorToken(Long userId) throws TwoFaException {
......
......@@ -91,6 +91,39 @@ public class LinotpConnection {
.build();
httpClient = HttpClients.custom().setDefaultRequestConfig(config).build();
}
public LinotpSimpleResponse checkToken(UserEntity user, String token) throws TwoFaException {
try {
HttpPost httpPost = new HttpPost(configMap.get("url") + "/validate/check");
List<NameValuePair> nvps = new ArrayList <NameValuePair>();
if (configMap.containsKey("userId"))
nvps.add(new BasicNameValuePair("user", configMap.get("userId")));
else
nvps.add(new BasicNameValuePair("user", user.getEppn()));
if (configMap.containsKey("realm"))
nvps.add(new BasicNameValuePair("realm", configMap.get("realm")));
nvps.add(new BasicNameValuePair("pass", token));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response = httpClient.execute(targetHost, httpPost, context);
try {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
logger.debug(responseString);
return resultParser.parseSimpleResponse(responseString);
} finally {
response.close();
}
} catch (ParseException | IOException e) {
throw new TwoFaException(e);
}
}
public LinotpInitAuthenticatorTokenResponse createAuthenticatorToken(UserEntity user) throws TwoFaException {
try {
......@@ -101,7 +134,7 @@ public class LinotpConnection {
nvps.add(new BasicNameValuePair("type", "totp"));
nvps.add(new BasicNameValuePair("otplen", "6"));
nvps.add(new BasicNameValuePair("genkey", "1"));
nvps.add(new BasicNameValuePair("hashlib", "sha256"));
nvps.add(new BasicNameValuePair("hashlib", "sha1"));
nvps.add(new BasicNameValuePair("timeStep", "30"));
nvps.add(new BasicNameValuePair("description", "This is a description"));
......
......@@ -12,6 +12,7 @@ package edu.kit.scc.webreg.session;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
......@@ -67,6 +68,8 @@ public class SessionManager implements Serializable {
private String locale;
private Date twoFaElevation;
@PostConstruct
public void init() {
serviceApproverList = new ArrayList<ServiceEntity>();
......@@ -265,4 +268,12 @@ public class SessionManager implements Serializable {
public List<ServiceEntity> getServiceSshPubKeyApproverList() {
return serviceSshPubKeyApproverList;
}
public Date getTwoFaElevation() {
return twoFaElevation;
}
public void setTwoFaElevation(Date twoFaElevation) {
this.twoFaElevation = twoFaElevation;
}
}
/*******************************************************************************
* 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.bean;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
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.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.LinotpSimpleResponse;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpTokenResultList;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
@ManagedBean
@ViewScoped
public class TwoFaLoginBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private SessionManager sessionManager;
@Inject
private FacesMessageGenerator messageGenerator;
@Inject
private UserService userService;
@Inject
private TwoFaService twoFaService;
private UserEntity user;
private LinotpTokenResultList tokenList;
private String tokenInput;
public void preRenderView(ComponentSystemEvent ev) {
if (user == null) {
user = userService.findById(sessionManager.getUserId());
try {
tokenList = twoFaService.findByUserId(sessionManager.getUserId());
} catch (TwoFaException e) {
messageGenerator.addErrorMessage("Error", e.toString());
logger.debug("Exception happened", e);
}
}
}
public void check() {
try {
LinotpSimpleResponse response = twoFaService.checkToken(sessionManager.getUserId(), tokenInput);
if (response.getResult() != null && response.getResult().isStatus() && response.getResult().isValue()) {
// Succesfull check
sessionManager.setTwoFaElevation(new Date());
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect(sessionManager.getOriginalRequestPath());
sessionManager.setOriginalRequestPath(null);
}
else {
messageGenerator.addResolvedWarningMessage("twofa_login_failed", "twofa_login_failed_detail", true);
tokenInput = "";
}
} 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");
}
}
public UserEntity getUser() {
return user;
}
public LinotpTokenResultList getTokenList() {
return tokenList;
}
public String getTokenInput() {
return tokenInput;
}
public void setTokenInput(String tokenInput) {
this.tokenInput = tokenInput;
}
}
......@@ -10,21 +10,26 @@
******************************************************************************/
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;
......@@ -49,20 +54,41 @@ 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) {
user = userService.findById(sessionManager.getUserId());
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());
}
}
......
my_twofa=Zweite Faktoren
twofa_list=Liste zweiter Faktor
accept_tou=Ich habe die Nutzungsbedingungen gelesen und bin einverstanden.
set_ssh_pub_key=SSH Key setzen
add_ssh_pub_key=SSH Key hochladen
......
my_twofa=Second factors
twofa_list=List of second factors
aa_entities=Attribute authorities
set_ssh_pub_key=Set SSH Key
add_ssh_pub_key=Add SSH Key
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<head>
<title></title>
</head>
<body>
<f:metadata>
<f:event type="javax.faces.event.PreRenderViewEvent"
listener="#{twoFaLoginBean.preRenderView}" />
</f:metadata>
<ui:composition template="/template/default.xhtml">
<ui:param name="title" value="#{messages.title}"/>
<ui:define name="content">
<h:form id="form" prependId="false">
<p:panel header="#{messages.twofa_login}">
<div style="margin-top: 8px; margin-bottom: 16px;"><h:outputText value="#{messages.twofa_login_text}"/></div>
<div><p:messages showDetail="true" /></div>
<p:focus conext="baseData" for="tokenText" />
<h:panelGrid id="baseData" columns="2" style="margin-bottom: 16px;">
<p:outputLabel for="@next" value="#{messages.twofa_code}"/>
<p:inputText id="tokenText" value="#{twoFaLoginBean.tokenInput}"/>
</h:panelGrid>
<p:commandButton id="check" action="#{twoFaLoginBean.check}" value="#{messages.check}"
update=":form" />
</p:panel>
<p:dataGrid var="token" value="#{twoFaLoginBean.tokenList}" columns="3" styleClass="whitefoot"
layout="grid" style="margin-top: 16px; margin-bottom: 16px;">
<p:panel styleClass="grayback" style="margin-bottom: 0px;">
<f:facet name="header">
<i class="fa fa-fw fa-key"></i>
<b><h:outputText value="#{token.serial}" /></b>
</f:facet>
<div><h:outputText value="#{token.tokenType}" /></div>
<div><h:outputText value="#{token.isactive}" /></div>
</p:panel>
</p:dataGrid>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
......@@ -41,7 +41,8 @@
<f:facet name="header">#{messages.twofa_list}</f:facet>
<p:panel styleClass="grayback" style="margin-bottom: 0px;">
<f:facet name="header">
<div><h:outputText value="#{token.serial}" /></div>
<i class="fa fa-fw fa-key"></i>
<b><h:outputText value="#{token.serial}" /></b>
</f:facet>
<div><h:outputText value="#{token.tokenType}" /></div>
<div><h:outputText value="#{token.isactive}" /></div>
......
Markdown is supported
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