Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Example X.509 Authentication Plugin

The following shows en example of an X.509 Authentication plugin you can use if you wish.

Code Block
languagejava
package dk.itp.security.auth;

import java.util.Hashtable;
import java.util.Properties;

import dk.itp.security.authentication.x509.AbstractX509CertificatePlugin;
import dk.itp.security.certificate.Subject;
import dk.itp.security.passticket.PTException;
import dk.itp.security.passticket.User;
import dk.itp.security.passticket.server.AuthErrorCodes;

/**
 * Authenticates users using OCES I and OCES II (DanID / NemID).
 * 
 * @author Kim Rasmussen
 * 
 */
public class SampleOCESAuthenticationPlugin extends AbstractX509CertificatePlugin {
	/**
	 * Returns the authentication level, the higher the level, the more secure this authentication is considered to be.
	 */
	public int getAuthenticationLevel() {
		return 20;
	}

	public String getName() {
		return "Sample OCES II Certificate plugin";
	}
	
	/**
	 * Returns the type of authentication, all plugins have assigned a particular id identifying that specify type
	 * of authentication.
	 */
	public int getAuthenticationType() {
		return dk.itp.security.passticket.AuthTypes.AUTHTYPE_X509_CA;
	}

	/**
	 * Try to login the specified user session, using the supplied userid and password.
	 * @param User this method will update the provided user object
	 * @param userid reserved
	 * @param credentials OCES login sign text
	 * @param newPassword not used
	 */
	public void login(User user, String userid, Object credentials) throws PTException {
		try {
			
			Subject subject = verifyCertificate(user, credentials.toString(), false, false, null, null);
			userid = subject.getSerialNumber();
			
			if (user.stateVariables == null)
				user.stateVariables = new Hashtable();
						
			user.stateVariables.put("company", subject.getO());
			user.stateVariables.put("country", subject.getC());
			user.stateVariables.put("full_subject", subject.getOrderedSubjectDN());
			user.stateVariables.put("certificate_serialnumber", subject.getCertificate().getSerialNumber().toString());
			if (subject.getEmailAddress() != null)
				user.stateVariables.put("email", subject.getEmailAddress());
			user.username = subject.getCn();

			String serial = subject.getSerialNumber();

			if (serial.startsWith("PID")) {
				user.stateVariables.put("pid", serial.substring(4));
			} else if (serial.startsWith("CVR")) {
				String cvr = serial.substring(4);
				if (cvr.indexOf('-') > 0)
					cvr = cvr.substring(0, cvr.indexOf('-'));
				user.stateVariables.put("cvr", cvr);

				int idx = serial.indexOf("-UID:");
				if (idx < 0) {
					idx = serial.indexOf("-RID:");
					if (idx >= 0) {
						// Medarbejder cert
						user.stateVariables.put("rid", serial.substring(idx + 5));
					}

				} else {
					// Virksomheds cert
					user.stateVariables.put("uid", serial.substring(idx + 5));
				}
			}

			// Add additional code here to lookup user groups from database etc.

			user.isLoggedOn = true;
		} catch(PTException e) {
			cat.warn("Exception trying to log user in", e);
			throw e;
		} 
	}
	
	public void confirm(User user, String signtext, Object credentials) throws PTException {
		// Verify Digital signatures here
		Subject subject = verifyCertificate(user, credentials.toString(), false, false, null, signtext);
		
		// Check that same certificate was used at login (you might not care, so remove this code if you do not).
		if (!user.stateVariables.get("certificate_serialnumber").equals(subject.getCertificate().getSerialNumber().toString()))
			throw new PTException("Wrong certificate used - should be the same certificate as the one used at login");
	}
}

...

And then list multiple keystores for each provider ID (ca.provider.xxxx.nemid.appletparam.ZZ.*) where ZZ is the provider ID. Your application which displays the applet can then choose between different providers and thus what is displayed in the applet by changing the provider ID used as input to NemIDAppletElementGenerator.

<%@ page isThreadSafe="true" import="dk.itp.security.passticket.*,dk.itp.portalprotect.nemid.NemIDAppletElementGenerator" %>

<%

  int NEMID_PROVIDERID = 10;

 

  String sessionId = request.getRemoteUser();

  NemIDAppletElementGenerator generator = new NemIDAppletElementGenerator(sessionId, AuthTypes.AUTHTYPE_X509_CA, NEMID_PROVIDERID ); // You might use another authtype here depending on your plugin, such as AuthTypes_AUTHTYPE_NEMID

 

  generator.setChallenge(“random_string_containing_challenge_value”);

  generator.setLogLevel("debug"); // INFO/DEBUG/ERROR

  generator.setUrlPrefix("https://applet.danid.dk");

   

  String applettag = generator.generateLogonAppletElement();

%>

 

<html>

<head><title>NemID Applet test</title></head>

<body>      

<script language="JavaScript">

function appletStarted() {

}

function onLogonOk(signature) {

  document.PPForm.message.value=signature;

  document.PPForm.action.value="logonok";

  document.PPForm.submit();

}

function onLogonCancel() {

  document.location="demologin.jsp";

}

function onLogonError(reason) {

  document.PPForm.message.value=reason;

  document.PPForm.action.value="logonerror";

  document.PPForm.submit();

}

</script>

 

<%=applettag%>

 

<form name="PPForm" method="post" action="/NemIDLoginServlet">

<input name="message" value="" type="hidden">

<input name="action" value="" type="hidden">

</form>

 

</body>

</html>