/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.restapi.security; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.olat.admin.user.delete.service.UserDeletionManager; import org.olat.basesecurity.AuthHelper; import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.util.StringHelper; import org.olat.login.auth.OLATAuthManager; /** * * Description:<br> * Authenticate against OLAT Provider * * <P> * Initial Date: 7 apr. 2010 <br> * @author srosse, stephane.rosse@frentix.com */ @Path("auth") public class Authentication { private static final String VERSION = "1.0"; /** * Retrieves the version of the User Authentication Web Service * @response.representation.200.mediaType text/plain * @response.representation.200.doc The version of this specific Web Service * @response.representation.200.example 1.0 * @return */ @GET @Path("version") @Produces(MediaType.TEXT_PLAIN) public Response getVersion() { return Response.ok(VERSION).build(); } /** * Authenticates against OLAT Provider and provides a security token if * authentication is successful. The security token is returned as * a header named X-OLAT-TOKEN. Given that the password is sent in clear text and not encrypted, it is not advisable * to use this service over a none secure connection (https). * @response.representation.200.mediaType text/plain, application/xml * @response.representation.200.doc Say hello to the authenticated user, and give it a security token * @response.representation.200.example <hello>Hello john</hello> * @response.representation.401.doc The authentication has failed * @response.representation.404.doc The identity not found * @param username The username * @param password The password (the password is in clear text, not encrypted) * @param httpRequest The HTTP request * @return */ @GET @Path("{username}") @Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) public Response login(@PathParam("username") String username, @QueryParam("password") String password, @QueryParam("x-olat-token") String secToken, @Context HttpServletRequest httpRequest) { if(StringHelper.containsNonWhitespace(password)) { return loginWithPassword(username, password, httpRequest); } else if (StringHelper.containsNonWhitespace(secToken)) { return loginWithToken(username, secToken, httpRequest); } return Response.serverError().status(Response.Status.BAD_REQUEST).build(); } private Response loginWithToken(String username, String secToken, HttpServletRequest httpRequest) { Identity identity = BaseSecurityManager.getInstance().findIdentityByName(username); if(identity == null) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } org.olat.basesecurity.Authentication auth = BaseSecurityManager.getInstance().findAuthentication(identity, RestSecurityBeanImpl.REST_AUTH_PROVIDER); if(auth == null) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } if(auth.getCredential() != null && auth.getCredential().equals(secToken)) { UserRequest ureq = RestSecurityHelper.getUserRequest(httpRequest); int loginStatus = AuthHelper.doHeadlessLogin(identity, RestSecurityBeanImpl.REST_AUTH_PROVIDER, ureq, true); if (loginStatus == AuthHelper.LOGIN_OK) { return Response.ok("<hello identityKey=\"" + identity.getKey() + "\">Hello " + username + "</hello>", MediaType.APPLICATION_XML) .header(RestSecurityHelper.SEC_TOKEN, secToken).build(); } } return Response.serverError().status(Status.UNAUTHORIZED).build(); } private Response loginWithPassword(String username, String password, HttpServletRequest httpRequest) { UserRequest ureq = RestSecurityHelper.getUserRequest(httpRequest); OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); Identity identity = olatAuthenticationSpi.authenticate(null, username, password); if(identity == null) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } int loginStatus = AuthHelper.doHeadlessLogin(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), ureq, true); if (loginStatus == AuthHelper.LOGIN_OK) { //fxdiff: FXOLAT-268 update last login date and register active user UserDeletionManager.getInstance().setIdentityAsActiv(identity); //Forge a new security token RestSecurityBean securityBean = CoreSpringFactory.getImpl(RestSecurityBean.class); String token = securityBean.generateToken(identity, httpRequest.getSession(true)); return Response.ok("<hello identityKey=\"" + identity.getKey() + "\">Hello " + username + "</hello>", MediaType.APPLICATION_XML) .header(RestSecurityHelper.SEC_TOKEN, token).build(); } return Response.serverError().status(Status.UNAUTHORIZED).build(); } }