dailidong
5 years ago
12 changed files with 515 additions and 44 deletions
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.EnumValue; |
||||||
|
|
||||||
|
/** |
||||||
|
* authentication type |
||||||
|
*/ |
||||||
|
public enum AuthenticationType { |
||||||
|
|
||||||
|
PASSWORD(0, "verify via user name and password"), |
||||||
|
; |
||||||
|
|
||||||
|
AuthenticationType(int code, String desc) { |
||||||
|
this.code = code; |
||||||
|
this.desc = desc; |
||||||
|
} |
||||||
|
|
||||||
|
@EnumValue |
||||||
|
private final int code; |
||||||
|
private final String desc; |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public interface Authenticator { |
||||||
|
/** |
||||||
|
* Verifying legality via username and password |
||||||
|
* @param username user name |
||||||
|
* @param password user password |
||||||
|
* @param extra extra info |
||||||
|
* @return result object |
||||||
|
*/ |
||||||
|
Result<Map<String, String>> authenticate(String username, String password, String extra); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get authenticated user |
||||||
|
* @param request http servlet request |
||||||
|
* @return user |
||||||
|
*/ |
||||||
|
User getAuthUser(HttpServletRequest request); |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.enums.Status; |
||||||
|
import org.apache.dolphinscheduler.api.service.SessionService; |
||||||
|
import org.apache.dolphinscheduler.api.service.UsersService; |
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.common.Constants; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.Session; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class PasswordAuthenticator implements Authenticator { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PasswordAuthenticator.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UsersService userService; |
||||||
|
@Autowired |
||||||
|
private SessionService sessionService; |
||||||
|
|
||||||
|
@Override |
||||||
|
public Result<Map<String, String>> authenticate(String username, String password, String extra) { |
||||||
|
Result<Map<String, String>> result = new Result<>(); |
||||||
|
// verify username and password
|
||||||
|
User user = userService.queryUser(username, password); |
||||||
|
if (user == null) { |
||||||
|
result.setCode(Status.USER_NAME_PASSWD_ERROR.getCode()); |
||||||
|
result.setMsg(Status.USER_NAME_PASSWD_ERROR.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
// create session
|
||||||
|
String sessionId = sessionService.createSession(user, extra); |
||||||
|
if (sessionId == null) { |
||||||
|
result.setCode(Status.LOGIN_SESSION_FAILED.getCode()); |
||||||
|
result.setMsg(Status.LOGIN_SESSION_FAILED.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
logger.info("sessionId : {}" , sessionId); |
||||||
|
result.setData(Collections.singletonMap(Constants.SESSION_ID, sessionId)); |
||||||
|
result.setCode(Status.SUCCESS.getCode()); |
||||||
|
result.setMsg(Status.LOGIN_SUCCESS.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public User getAuthUser(HttpServletRequest request) { |
||||||
|
Session session = sessionService.getSession(request); |
||||||
|
if (session == null) { |
||||||
|
logger.info("session info is null "); |
||||||
|
return null; |
||||||
|
} |
||||||
|
//get user object from session
|
||||||
|
return userService.queryUser(session.getUserId()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class SecurityConfig { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); |
||||||
|
|
||||||
|
@Value("${security.authentication.type:PASSWORD}") |
||||||
|
private String type; |
||||||
|
|
||||||
|
private AutowireCapableBeanFactory beanFactory; |
||||||
|
private AuthenticationType authenticationType; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
public SecurityConfig(AutowireCapableBeanFactory beanFactory) { |
||||||
|
this.beanFactory = beanFactory; |
||||||
|
} |
||||||
|
|
||||||
|
private void setAuthenticationType(String type) { |
||||||
|
if (StringUtils.isBlank(type)) { |
||||||
|
logger.info("security.authentication.type configuration is empty, the default value 'PASSWORD'"); |
||||||
|
this.authenticationType = AuthenticationType.PASSWORD; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
this.authenticationType = AuthenticationType.valueOf(type); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "authenticator") |
||||||
|
public Authenticator authenticator() { |
||||||
|
setAuthenticationType(type); |
||||||
|
Authenticator authenticator; |
||||||
|
switch (authenticationType) { |
||||||
|
case PASSWORD: |
||||||
|
authenticator = new PasswordAuthenticator(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new IllegalStateException("Unexpected value: " + authenticationType); |
||||||
|
} |
||||||
|
beanFactory.autowireBean(authenticator); |
||||||
|
return authenticator; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.interceptor; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.apache.dolphinscheduler.api.security.Authenticator; |
||||||
|
import org.apache.dolphinscheduler.common.enums.UserType; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.apache.dolphinscheduler.dao.mapper.UserMapper; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import static org.mockito.Mockito.when; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
public class LoginHandlerInterceptorTest { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LoginHandlerInterceptorTest.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
LoginHandlerInterceptor interceptor; |
||||||
|
@MockBean |
||||||
|
private Authenticator authenticator; |
||||||
|
@MockBean |
||||||
|
private UserMapper userMapper; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPreHandle() { |
||||||
|
HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
||||||
|
HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
||||||
|
// test no token and no cookie
|
||||||
|
Assert.assertFalse(interceptor.preHandle(request, response, null)); |
||||||
|
|
||||||
|
User mockUser = new User(); |
||||||
|
mockUser.setId(1); |
||||||
|
mockUser.setUserType(UserType.GENERAL_USER); |
||||||
|
|
||||||
|
// test no token
|
||||||
|
when(authenticator.getAuthUser(request)).thenReturn(mockUser); |
||||||
|
Assert.assertTrue(interceptor.preHandle(request, response, null)); |
||||||
|
|
||||||
|
// test token
|
||||||
|
String token = "123456"; |
||||||
|
when(request.getHeader("token")).thenReturn(token); |
||||||
|
when(userMapper.queryUserByToken(token)).thenReturn(mockUser); |
||||||
|
Assert.assertTrue(interceptor.preHandle(request, response, null)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.apache.dolphinscheduler.api.enums.Status; |
||||||
|
import org.apache.dolphinscheduler.api.service.SessionService; |
||||||
|
import org.apache.dolphinscheduler.api.service.UsersService; |
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.Session; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
import static org.mockito.Mockito.*; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
public class PasswordAuthenticatorTest { |
||||||
|
private static Logger logger = LoggerFactory.getLogger(PasswordAuthenticatorTest.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private AutowireCapableBeanFactory beanFactory; |
||||||
|
@MockBean |
||||||
|
private SessionService sessionService; |
||||||
|
@MockBean |
||||||
|
private UsersService usersService; |
||||||
|
|
||||||
|
private PasswordAuthenticator authenticator; |
||||||
|
|
||||||
|
private User mockUser; |
||||||
|
private Session mockSession; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() throws Exception { |
||||||
|
authenticator = new PasswordAuthenticator(); |
||||||
|
beanFactory.autowireBean(authenticator); |
||||||
|
|
||||||
|
mockUser = new User(); |
||||||
|
mockUser.setUserName("test"); |
||||||
|
mockUser.setEmail("test@test.com"); |
||||||
|
mockUser.setUserPassword("test"); |
||||||
|
mockUser.setId(1); |
||||||
|
|
||||||
|
mockSession = new Session(); |
||||||
|
mockSession.setId(UUID.randomUUID().toString()); |
||||||
|
mockSession.setIp("127.0.0.1"); |
||||||
|
mockSession.setUserId(1); |
||||||
|
mockSession.setLastLoginTime(new Date()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAuthenticate() { |
||||||
|
when(usersService.queryUser("test", "test")).thenReturn(mockUser); |
||||||
|
when(sessionService.createSession(mockUser, "127.0.0.1")).thenReturn(mockSession.getId()); |
||||||
|
Result result = authenticator.authenticate("test", "test", "127.0.0.1"); |
||||||
|
Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); |
||||||
|
logger.info(result.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGetAuthUser() { |
||||||
|
HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
||||||
|
when(usersService.queryUser(mockUser.getId())).thenReturn(mockUser); |
||||||
|
when(sessionService.getSession(request)).thenReturn(mockSession); |
||||||
|
|
||||||
|
User user = authenticator.getAuthUser(request); |
||||||
|
Assert.assertNotNull(user); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.test.context.TestPropertySource; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
@TestPropertySource(properties = { |
||||||
|
"security.authentication.type=PASSWORD", |
||||||
|
}) |
||||||
|
public class SecurityConfigTest { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private SecurityConfig securityConfig; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAuthenticator() { |
||||||
|
Authenticator authenticator = securityConfig.authenticator(); |
||||||
|
Assert.assertNotNull(authenticator); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue