diff --git a/app/index.js b/app/index.js
index 7b30aa8be8e3240084bb9fadba4cda4fe1a0328f..7a3d8effe5aac79ec9c08c1852430e2aa9f62be4 100644
--- a/app/index.js
+++ b/app/index.js
@@ -62,9 +62,9 @@ const OutsideStack = createStackNavigator({
 	defaultNavigationOptions: defaultHeader
 });
 
-const OAuthStack = createStackNavigator({
-	OAuthView: {
-		getScreen: () => require('./views/OAuthView').default
+const AuthenticationWebViewStack = createStackNavigator({
+	AuthenticationWebView: {
+		getScreen: () => require('./views/AuthenticationWebView').default
 	}
 }, {
 	defaultNavigationOptions: defaultHeader
@@ -72,7 +72,7 @@ const OAuthStack = createStackNavigator({
 
 const OutsideStackModal = createStackNavigator({
 	OutsideStack,
-	OAuthStack
+	AuthenticationWebViewStack
 },
 {
 	mode: 'modal',
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index 325daa987435c89dbec3c4f679f323db4e080a80..d3efaa4b3d0f04771e6a0c888ba989feb2ac319f 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -297,7 +297,7 @@ const RocketChat = {
 		}
 	},
 
-	async loginOAuth(params) {
+	async loginOAuthOrSso(params) {
 		try {
 			const result = await this.login(params);
 			reduxStore.dispatch(loginRequest({ resume: result.token }));
@@ -776,15 +776,15 @@ const RocketChat = {
 	},
 	async getLoginServices(server) {
 		try {
-			let loginServicesFilter = [];
+			let loginServices = [];
 			const loginServicesResult = await fetch(`${ server }/api/v1/settings.oauth`).then(response => response.json());
 
 			if (loginServicesResult.success && loginServicesResult.services.length > 0) {
 				const { services } = loginServicesResult;
-				loginServicesFilter = services.filter(item => item.custom !== undefined); // TODO: remove this after SAML and CAS
+				loginServices = services;
 
-				const loginServicesReducer = loginServicesFilter.reduce((ret, item) => {
-					const name = item.name ? item.name : item.service;
+				const loginServicesReducer = loginServices.reduce((ret, item) => {
+					const name = item.name || item.buttonLabelText || item.service;
 					const authType = this._determineAuthType(item);
 
 					if (authType !== 'not_supported') {
@@ -795,21 +795,25 @@ const RocketChat = {
 				}, {});
 				reduxStore.dispatch(setLoginServices(loginServicesReducer));
 			}
-			return Promise.resolve(loginServicesFilter.length);
+			return Promise.resolve(loginServices.length);
 		} catch (error) {
 			console.warn(error);
 			return Promise.reject();
 		}
 	},
-	_determineAuthType(service) {
-		// TODO: remove this after other oauth providers are implemented. e.g. Drupal, github_enterprise
-		const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter'];
-		const { name, custom } = service;
+	_determineAuthType(services) {
+		const { name, custom, service } = services;
 
 		if (custom) {
 			return 'oauth_custom';
 		}
 
+		if (service === 'saml') {
+			return 'saml';
+		}
+
+		// TODO: remove this after other oauth providers are implemented. e.g. Drupal, github_enterprise
+		const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter'];
 		return availableOAuth.includes(name) ? 'oauth' : 'not_supported';
 	},
 	getUsernameSuggestion() {
diff --git a/app/views/OAuthView.js b/app/views/AuthenticationWebView.js
similarity index 58%
rename from app/views/OAuthView.js
rename to app/views/AuthenticationWebView.js
index eee46c158a08e45303c9da4c8d8345d35c6df6ef..2895f3cee78a6c08b53e31de111dd4cd83d901fd 100644
--- a/app/views/OAuthView.js
+++ b/app/views/AuthenticationWebView.js
@@ -24,11 +24,14 @@ const styles = StyleSheet.create({
 	}
 });
 
-class OAuthView extends React.PureComponent {
-	static navigationOptions = ({ navigation }) => ({
-		headerLeft: <CloseModalButton navigation={navigation} />,
-		title: 'OAuth'
-	})
+class AuthenticationWebView extends React.PureComponent {
+	static navigationOptions = ({ navigation }) => {
+		const authType = navigation.getParam('authType', 'oauth');
+		return {
+			headerLeft: <CloseModalButton navigation={navigation} />,
+			title: authType === 'saml' ? 'SSO' : 'OAuth'
+		};
+	}
 
 	static propTypes = {
 		navigation: PropTypes.object,
@@ -41,6 +44,7 @@ class OAuthView extends React.PureComponent {
 			logging: false,
 			loading: false
 		};
+		this.authType = props.navigation.getParam('authType', 'oauth');
 		this.redirectRegex = new RegExp(`(?=.*(${ props.server }))(?=.*(credentialToken))(?=.*(credentialSecret))`, 'g');
 	}
 
@@ -58,7 +62,7 @@ class OAuthView extends React.PureComponent {
 		this.setState({ logging: true });
 
 		try {
-			await RocketChat.loginOAuth(params);
+			await RocketChat.loginOAuthOrSso(params);
 		} catch (e) {
 			console.warn(e);
 		}
@@ -66,29 +70,45 @@ class OAuthView extends React.PureComponent {
 		this.dismiss();
 	}
 
+	onNavigationStateChange = (webViewState) => {
+		const url = decodeURIComponent(webViewState.url);
+		if (this.authType === 'saml') {
+			const { navigation } = this.props;
+			const ssoToken = navigation.getParam('ssoToken');
+			if (url.includes('ticket') || url.includes('validate')) {
+				const payload = `{ "saml": true, "credentialToken": "${ ssoToken }" }`;
+				// We need to set a timeout when the login is done with SSO in order to make it work on our side.
+				// It is actually due to the SSO server processing the response.
+				setTimeout(() => {
+					this.login(JSON.parse(payload));
+				}, 3000);
+			}
+		}
+
+		if (this.authType === 'oauth') {
+			if (this.redirectRegex.test(url)) {
+				const parts = url.split('#');
+				const credentials = JSON.parse(parts[1]);
+				this.login({ oauth: { ...credentials } });
+			}
+		}
+	}
+
 	render() {
 		const { navigation } = this.props;
 		const { loading } = this.state;
-		const oAuthUrl = navigation.getParam('oAuthUrl');
+		const uri = navigation.getParam('url');
 		return (
 			<React.Fragment>
 				<StatusBar />
 				<WebView
 					useWebKit
-					source={{ uri: oAuthUrl }}
+					source={{ uri }}
 					userAgent={userAgent}
-					onNavigationStateChange={(webViewState) => {
-						const url = decodeURIComponent(webViewState.url);
-						if (this.redirectRegex.test(url)) {
-							const parts = url.split('#');
-							const credentials = JSON.parse(parts[1]);
-							this.login({ oauth: { ...credentials } });
-						}
-					}}
+					onNavigationStateChange={this.onNavigationStateChange}
 					onLoadStart={() => {
 						this.setState({ loading: true });
 					}}
-
 					onLoadEnd={() => {
 						this.setState({ loading: false });
 					}}
@@ -103,4 +123,4 @@ const mapStateToProps = state => ({
 	server: state.server.server
 });
 
-export default connect(mapStateToProps)(OAuthView);
+export default connect(mapStateToProps)(AuthenticationWebView);
diff --git a/app/views/LoginSignupView.js b/app/views/LoginSignupView.js
index 8184c9a8a6673230eeb391b171f1f5052fa2c1a1..36e530e5a85df31c26b7c4636bc3b4f1748b5602 100644
--- a/app/views/LoginSignupView.js
+++ b/app/views/LoginSignupView.js
@@ -156,7 +156,7 @@ class LoginSignupView extends React.Component {
 		const scope = 'email';
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&scope=${ scope }&state=${ state }&display=touch`;
-		this.openOAuth(`${ endpoint }${ params }`);
+		this.openOAuth({ url: `${ endpoint }${ params }` });
 	}
 
 	onPressGithub = () => {
@@ -167,7 +167,7 @@ class LoginSignupView extends React.Component {
 		const scope = 'user:email';
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&scope=${ scope }&state=${ state }`;
-		this.openOAuth(`${ endpoint }${ encodeURIComponent(params) }`);
+		this.openOAuth({ url: `${ endpoint }${ encodeURIComponent(params) }` });
 	}
 
 	onPressGitlab = () => {
@@ -179,7 +179,7 @@ class LoginSignupView extends React.Component {
 		const scope = 'read_user';
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&scope=${ scope }&state=${ state }&response_type=code`;
-		this.openOAuth(`${ endpoint }${ params }`);
+		this.openOAuth({ url: `${ endpoint }${ params }` });
 	}
 
 	onPressGoogle = () => {
@@ -190,7 +190,7 @@ class LoginSignupView extends React.Component {
 		const scope = 'email';
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&scope=${ scope }&state=${ state }&response_type=code`;
-		this.openOAuth(`${ endpoint }${ params }`);
+		this.openOAuth({ url: `${ endpoint }${ params }` });
 	}
 
 	onPressLinkedin = () => {
@@ -201,7 +201,7 @@ class LoginSignupView extends React.Component {
 		const scope = 'r_emailaddress';
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&scope=${ scope }&state=${ state }&response_type=code`;
-		this.openOAuth(`${ endpoint }${ params }`);
+		this.openOAuth({ url: `${ endpoint }${ params }` });
 	}
 
 	onPressMeteor = () => {
@@ -211,14 +211,14 @@ class LoginSignupView extends React.Component {
 		const redirect_uri = `${ server }/_oauth/meteor-developer`;
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirect_uri }&state=${ state }&response_type=code`;
-		this.openOAuth(`${ endpoint }${ params }`);
+		this.openOAuth({ url: `${ endpoint }${ params }` });
 	}
 
 	onPressTwitter = () => {
 		const { server } = this.props;
 		const state = this.getOAuthState();
 		const url = `${ server }/_oauth/twitter/?requestTokenAndRedirect=true&state=${ state }`;
-		this.openOAuth(url);
+		this.openOAuth({ url });
 	}
 
 	onPressCustomOAuth = (loginService) => {
@@ -230,7 +230,16 @@ class LoginSignupView extends React.Component {
 		const state = this.getOAuthState();
 		const params = `?client_id=${ clientId }&redirect_uri=${ redirectUri }&response_type=code&state=${ state }&scope=${ scope }`;
 		const url = `${ serverURL }${ authorizePath }${ params }`;
-		this.openOAuth(url);
+		this.openOAuth({ url });
+	}
+
+	onPressSaml = (loginService) => {
+		const { server } = this.props;
+		const {	clientConfig } = loginService;
+		const {	provider } = clientConfig;
+		const ssoToken = random(17);
+		const url = `${ server }/_saml/authorize/${ provider }/${ ssoToken }`;
+		this.openOAuth({ url, ssoToken, authType: 'saml' });
 	}
 
 	getOAuthState = () => {
@@ -238,9 +247,9 @@ class LoginSignupView extends React.Component {
 		return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true }));
 	}
 
-	openOAuth = (oAuthUrl) => {
+	openOAuth = ({ url, ssoToken, authType = 'oauth' }) => {
 		const { navigation } = this.props;
-		navigation.navigate('OAuthView', { oAuthUrl });
+		navigation.navigate('AuthenticationWebView', { url, authType, ssoToken });
 	}
 
 	login = () => {
@@ -317,7 +326,6 @@ class LoginSignupView extends React.Component {
 		let { name } = service;
 		name = name === 'meteor-developer' ? 'meteor' : name;
 		const icon = `icon_${ name }`;
-		name = name.charAt(0).toUpperCase() + name.slice(1);
 		let onPress = () => {};
 
 		switch (service.authType) {
@@ -329,16 +337,29 @@ class LoginSignupView extends React.Component {
 				onPress = () => this.onPressCustomOAuth(service);
 				break;
 			}
+			case 'saml': {
+				onPress = () => this.onPressSaml(service);
+				break;
+			}
 			default:
 				break;
 		}
+		name = name.charAt(0).toUpperCase() + name.slice(1);
+		let buttonText;
+		if (service.service === 'saml') {
+			buttonText = <Text style={styles.serviceName}>{name}</Text>;
+		} else {
+			buttonText = (
+				<>
+					{I18n.t('Continue_with')} <Text style={styles.serviceName}>{name}</Text>
+				</>
+			);
+		}
 		return (
 			<RectButton key={service.name} onPress={onPress} style={styles.serviceButton}>
 				<View style={styles.serviceButtonContainer}>
 					{service.authType === 'oauth' ? <Image source={{ uri: icon }} style={styles.serviceIcon} /> : null}
-					<Text style={styles.serviceText}>
-						{I18n.t('Continue_with')} <Text style={styles.serviceName}>{name}</Text>
-					</Text>
+					<Text style={styles.serviceText}>{buttonText}</Text>
 				</View>
 			</RectButton>
 		);